Spring Integration 4.0 终究 到来了, 而这一次发布带来了十分棒的特征. 本文中讲到的这个特征是完整不运用XML来设置装备摆设一个集成流的可能性. 那些不爱好XML的人们将可以只运用JavaConfig开发一个集成使用顺序.
本文分红以下几个部分:
引见.
流的概述.
Spring 设置装备摆设.
端点的具体信息.
测试全部流.
总结.
可以在 github 上找到本文相干的源代码.
在这个示例中被挪用的web服务的源代码可以在 github 上的 srping-samples资本库中找到.
这个示例使用顺序展现了怎么设置装备摆设一些音讯和集成端点. 用户经过一个course的Id恳求一个 course . 流将会挪用一个web服务并向用户做出回应. 另外,一些类型的course将会被存储到一个数据库中.
这个流以下所示:
一个集成的 网关 (course 服务) 为音讯系统供给词条的服务.
一个 转换器 构建来自用户指定的course Id的恳求音讯.
一个web服务的 出站网关 将恳求发送到一个web服务并等候其回应.
一个 服务履行器 被注册到回应通道,以向用户前往course的称号.
一个 过滤器 也会被注册到回应通道. 这个过滤器会发送一些类型的course到一个mongodb 通道适配器 以将回应存储到一个数据库.
下图较好的展现了这个流是怎么结构的:
如在引见一节所会商的,全部设置装备摆设都是用JavaConfig来设置装备摆设. 这一设置装备摆设被分红了三个文件:根底设备,web服务和数据库设置装备摆设. 让我们来一瞧终究:
这个设置装备摆设文件值包括了音讯通道的定义. 音讯端点(转换器,过滤器等等..)是用了注解来设置装备摆设.
InfrastructureConfiguration.java
@Configuration @ComponentScan("xpadro.spring.integration.endpoint") //@Component @IntegrationComponentScan("xpadro.spring.integration.gateway") //@MessagingGateway @EnableIntegration @Import({MongoDBConfiguration.class, WebServiceConfiguration.class}) public class InfrastructureConfiguration { @Bean @Description("Entry to the messaging system through the gateway.") public MessageChannel requestChannel() { return new DirectChannel(); } @Bean @Description("Sends request messages to the web service outbound gateway") public MessageChannel invocationChannel(@Qualifier("wsOutboundGateway") MessageHandler wsOutboundGateway) { DirectChannel channel = new DirectChannel(); channel.subscribe(wsOutboundGateway); return channel; } @Bean @Description("Sends web service responses to both the client and a database") public MessageChannel responseChannel() { return new PublishSubscribeChannel(); } @Bean @Description("Stores non filtered messages to the database") public MessageChannel storeChannel(@Qualifier("mongodbAdapter") MessageHandler mongoOutboundAdapter) { DirectChannel channel = new DirectChannel(); channel.subscribe(mongoOutboundAdapter); return channel; } }
@ComponentScan 注解会搜刮运用了 @Component 注解的类, 这类类是我们定义的音讯端点; 过滤器,转换器和服务履行器.
@IntegrationComponentScan 注解搜刮指定的集成注解. 在我们的示例中,它将会扫描到运用@MessagingGateway注解的词条网关.
@EnableIntegration 注解启动了集成设置装备摆设. 例如,像@Transformer 或者 @Filter这类办法级此外注解.
这一设置装备摆设文件设置装备摆设的web服务的出站恳求网关及其所需求的编组.
WebServiceConfiguration.java
@Configuration public class WebServiceConfiguration { @Bean public MessageHandler wsOutboundGateway() { MarshallingWebServiceOutboundGateway gw = new MarshallingWebServiceOutboundGateway("http://localhost:8080/spring-ws-courses/courses", jaxb2Marshaller()); gw.setOutputChannelName("responseChannel"); return gw; } @Bean public Jaxb2Marshaller jaxb2Marshaller() { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); marshaller.setContextPath("xpadro.spring.integration.ws.types"); return marshaller; } }
网关可让我们定义它的输出通道,而不是它的输出通道. 我可以将网存眷册到通道来做到(见后面大节的invocationChannel 定义).
这一设置装备摆设文件定义了一切用来设置 mongoDB 所必须的bean. 它也定义了 mongoDB 出站通道适配器.
MongoDBConfiguration.java
@Configuration public class MongoDBConfiguration { @Bean public MongoDbFactory mongoDbFactory() throws Exception { return new SimpleMongoDbFactory(new MongoClient(), "si4Db"); } @Bean public MessageHandler mongodbAdapter() throws Exception { MongoDbStoringMessageHandler adapter = new MongoDbStoringMessageHandler(mongoDbFactory()); adapter.setCollectionNameExpression(new LiteralExpression("courses")); return adapter; } }
像是web服务的网关,我们不克不及为适配器设置输出通道. 异样也能够经过将其注册到存储通道来做到.
流的第一个端点是集成网关,它将会把参数(courseId)放到一个音讯的载荷中,并将其发送到恳求通道.
@MessagingGateway(name = "entryGateway", defaultRequestChannel = "requestChannel") public interface CourseService { public String findCourse(String courseId); }
包括courseId的音讯将会抵达转换器. 这个端点将构建web服务所需求的恳求工具
@Component public class CourseRequestBuilder { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Transformer(inputChannel="requestChannel", outputChannel="invocationChannel") public GetCourseRequest buildRequest(Message<String> msg) { logger.info("Building request for course [{}]", msg.getPayload()); GetCourseRequest request = new GetCourseRequest(); request.setCourseId(msg.getPayload()); return request; } }
注册到web服务回应将会被发送出去的回应通道,将会有一个服务履行器承受回应音讯并向客户机传送course称号:
@Component public class CourseResponseHandler { private Logger logger = LoggerFactory.getLogger(this.getClass()); @ServiceActivator(inputChannel="responseChannel") public String getResponse(Message<GetCourseResponse> msg) { GetCourseResponse course = msg.getPayload(); logger.info("Course with ID [{}] received: {}", course.getCourseId(), course.getName()); return course.getName(); } }
异样假如course需求被存储到一个数据库,一个过滤器就会注册到回应通道, 基于它的类型来做出决议,:
@Component public class StoredCoursesFilter { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Filter(inputChannel="responseChannel", outputChannel="storeChannel") public boolean filterCourse(Message<GetCourseResponse> msg) { if (!msg.getPayload().getCourseId().startsWith("BC-")) { logger.info("Course [{}] filtered. Not a BF course", msg.getPayload().getCourseId()); return false; } logger.info("Course [{}] validated. Storing to database", msg.getPayload().getCourseId()); return true; } }
下面的客户机将会遭到两个恳求:一个BC类型的course恳求将会被存储到数据库,另有一个DF类型的course将会终极被过滤掉:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes={InfrastructureConfiguration.class}) public class TestApp { @Autowired CourseService service; @Test public void testFlow() { String courseName = service.findCourse("BC-45"); assertNotNull(courseName); assertEquals("Introduction to Java", courseName); courseName = service.findCourse("DF-21"); assertNotNull(courseName); assertEquals("Functional Programming Principles in Scala", courseName); } }
这将会招致以下的把持台输出:
CourseRequestBuilder|Building request for course [BC-45] CourseResponseHandler|Course with ID [BC-45] received: Introduction to Java StoredCoursesFilter|Course [BC-45] validated. Storing to database CourseRequestBuilder|Building request for course [DF-21] CourseResponseHandler|Course with ID [DF-21] received: Functional Programming Principles in Scala StoredCoursesFilter|Course [DF-21] filtered. Not a BF course
我们曾经了解了怎么设置并测试一个由Spring Integration驱动的没有运用XML设置装备摆设的使用顺序. 敬请坚持存眷,由于带有 Spring Integration 扩大 的 Spring Integration Java DSL正在开展中!
我正把我的新文章发布到 Google+ 和 Twitter. 假如你想要看到新内容的更新音讯,请存眷我吧.
2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务