Spring Integration 4.0:完整的无XML示例

1.简介

Spring Integration 4.0终于发布了 ,并且此版本具有非常好的功能。 本文介绍的一种可能性是完全不使用XML即可配置集成流程。 那些不喜欢XML的人仅使用JavaConfig就可以开发集成应用程序。

本文分为以下几节:

  1. 介绍。
  2. 流程概述。
  3. 弹簧配置。
  4. 端点的详细信息。
  5. 测试整个流程。
  6. 结论。
  • 源代码可以在github上找到。
  • 在此示例中调用的Web服务的源代码可以在github的spring-samples存储库中找到。

2.流程概述

该示例应用程序显示了如何配置多个消息传递和集成端点。 用户通过指定课程ID来请求课程。 该流程将调用Web服务,并将响应返回给用户。 此外,某些类型的课程将存储到数据库中。

流程如下:

  • 集成网关 (课程服务)用作消息传递系统的入口。
  • 转换器根据用户指定的课程ID生成请求消息。
  • Web服务出站网关将请求发送到Web服务并等待响应。
  • 服务激活器订阅了响应通道,以便将课程名称返回给用户。
  • 过滤器也订阅了响应通道。 此过滤器会将某些类型的课程发送到mongodb 通道适配器 ,以便将响应存储到数据库。

下图更好地显示了流程的结构:
int-v4-full-flow_v2

3.弹簧配置

如简介部分所述,整个配置是使用JavaConfig定义的。 此配置分为三个文件:基础结构,Web服务和数据库配置。 让我们来看看:

3.1基础架构配置

该配置文件仅包含消息通道的定义。 消息传递端点(变压器,过滤器等)配置有注释。

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() {return new DirectChannel();}@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() {return new DirectChannel();}
}

@ComponentScan注释搜索@Component注释的类,它们是我们定义的消息传递终结点; 过滤器,变压器和服务激活器。

@IntegrationComponentScan批注搜索特定的集成批注。 在我们的示例中,它将扫描用@MessagingGateway注释的入口网关。

@EnableIntegration批注启用集成配置。 例如,方法级别的注释,例如@Transformer或@Filter。

3.2 Web服务配置

此配置文件配置Web服务出站网关及其必需的编组器。

WebServiceConfiguration.java

@Configuration
public class WebServiceConfiguration {@Bean@ServiceActivator(inputChannel = "invocationChannel")public MessageHandler wsOutboundGateway() {MarshallingWebServiceOutboundGateway gw = new MarshallingWebServiceOutboundGateway("http://localhost:8080/spring-ws-courses/courses", jaxb2Marshaller());gw.setOutputChannelName("responseChannel");return gw;}@Beanpublic Jaxb2Marshaller jaxb2Marshaller() {Jaxb2Marshaller marshaller = new Jaxb2Marshaller();marshaller.setContextPath("xpadro.spring.integration.ws.types");return marshaller;}
}

网关允许我们定义其输出通道,但不能定义输入通道。 我们需要使用@ServiceActivator注释适配器,以便将其订阅到调用通道,并避免必须在消息通道Bean定义中自动装配适配器。

3.3数据库配置

该配置文件定义了设置mongoDB所需的所有必需bean。 它还定义了mongoDB出站通道适配器。

MongoDBConfiguration.java

@Configuration
public class MongoDBConfiguration {@Beanpublic MongoDbFactory mongoDbFactory() throws Exception {return new SimpleMongoDbFactory(new MongoClient(), "si4Db");}@Bean@ServiceActivator(inputChannel = "storeChannel")public MessageHandler mongodbAdapter() throws Exception {MongoDbStoringMessageHandler adapter = new MongoDbStoringMessageHandler(mongoDbFactory());adapter.setCollectionNameExpression(new LiteralExpression("courses"));return adapter;}
}

像Web服务网关一样,我们无法将输入通道设置为适配器。 我还通过在@ServiceActivator批注中指定输入通道来完成此操作。

4.端点的细节

流的第一个端点是集成网关,它将把参数(courseId)放入消息的有效负载中并将其发送到请求通道。

@MessagingGateway(name = "entryGateway", defaultRequestChannel = "requestChannel")
public interface CourseService {public String findCourse(String courseId);
}

包含课程ID的消息将到达转换器。 该端点将构建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服务回复的通道,有一个服务激活器将接收响应消息并将课程名称传递给客户端:

@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();}
}

同样需要订阅响应通道的过滤器,将根据其类型决定是否将课程存储到数据库:

@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;}
}

5.测试整个流程

以下客户端将发送两个请求; BC类型的课程请求将被存储到数据库中,而DF类型的课程将被最终过滤:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={InfrastructureConfiguration.class})
public class TestApp {@AutowiredCourseService service;@Testpublic 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 JavaStoredCoursesFilter|Course [BC-45] validated. Storing to databaseCourseRequestBuilder|Building request for course [DF-21]CourseResponseHandler|Course with ID [DF-21] received: Functional Programming Principles in ScalaStoredCoursesFilter|Course [DF-21] filtered. Not a BF course

六,结论

我们已经学习了如何在不使用XML配置的情况下设置和测试支持Spring Integration的应用程序。 请继续关注,因为带有Spring Integration 扩展的 Spring Integration Java DSL即将推出!

翻译自: https://www.javacodegeeks.com/2014/05/spring-integration-4-0-a-complete-xml-free-example.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363327.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

http协议组成(请求状态码)

http请求由&#xff1a;请求行&#xff1b;消息报头&#xff1b;请求正文组成 //请求行 Request URL: http://172.32.4.33:8080/operation/v2/autoServer/queryAutoServer.htm //请求地址 Request Method: POST …

CSS伪类的三种写法

今天逛蓝色时&#xff0c;无意发现了有人讨论伪类的正确写法&#xff0c;让我对伪类的认识也更清晰了&#xff0c;转贴于此&#xff0c;以备日后查询(原贴当时没记下地址&#xff0c;已经记不得了) Code<style>a.tb{text-decoration:none;}a.tb:link{color:#FF9900;}a.tb…

sql自动生成golang结构体struct实体类

废话不多说直接上地址 使用地址http://www.linkinstars.com:8090/auto-code 项目github https://github.com/LinkinStars/Auto-Coding 是上次内容的一个更新&#xff0c;方便自己用&#xff0c;希望你也喜欢https://www.cnblogs.com/linkstar/p/10037629.html &#xff08;半个…

如何通过示例在Java中使用CopyOnWriteArraySet

CopyOnWriteArraySet是CopyOnWriteArrayList类的弟弟。 这些是专用集合类&#xff0c;这些类是在JDK 1.5上添加的&#xff0c;以及它们最流行的表亲ConcurrentHashMap 。 它们是并发收集框架的一部分&#xff0c;位于java.util.concurrent包中。 CopyOnWriteArraySet最适合作为…

生成器

一、什么是生成器 通过列表生成式&#xff0c;我们可以直接创建一个列表。但是&#xff0c;受到内存限制&#xff0c;列表容量是有限的。而且&#xff0c;创建一个包含100万个元素的列表&#xff0c;不仅占用很大的存储空间&#xff0c;如果我们仅仅需要访问前面几个元素&#…

VS2008快捷键大全

CtrlmCrtro折叠所有大纲CtrlMCrtrP: 停止大纲显示CtrlKCrtrC: 注释选定内容CtrlKCrtrU: 取消选定注释内容CtrlJ : 列出成员 智能感知ShiftAltEnter: 切换全屏编辑CtrlB,T / CtrlK,K: 切换书签开关CtrlB,N / CtrlK,N: 移动到下一书签 CtrlB,P: 移动到上一书签 CtrlB,C: 清除全部…

jQuery 入口函数主要有4种写法

jqery 入口函数主要有4种写法&#xff0c;其中以第3种方法最为方便。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

面向对象的三大特征 封装继承多态

面向对象设计 和开发程序的好处 交流更加流畅 、提高设计和开发效率 封装将类的某些信息隐藏在类内部&#xff0c;不允许外部程序直接访问&#xff0c;而是通过该类提供的方法来实现对隐藏信息的操作和访问私有化属性 提供公有化的访问方法 保证数据的安全性封装的步骤 …

Spring / Hibernate应用程序的性能调优

对于大多数典型的Spring / Hibernate企业应用程序&#xff0c;应用程序性能几乎完全取决于其持久层的性能。 这篇文章将讨论如何确认我们是否存在“数据库绑定”应用程序&#xff0c;然后逐步讲解7个经常使用的“快速取胜”技巧&#xff0c;这些技巧可以帮助提高应用程序性能。…

我的学习开发环境,呵呵!

今天到电子市场去&#xff0c;花了近700块&#xff0c;弄了块ARM的学习单板&#xff0c;再也不用去搞什么虚拟机了&#xff01; 简单的看了一下开发手册&#xff0c;还有点麻烦&#xff0c;可能得花点时间去把它搞清楚&#xff01; 但这块单板的功能还是很强的&#xff0c;基本…

Java on Windows Mobile

Moved to http://blog.tangcs.com/2008/05/29/java-on-windows-mobile/转载于:https://www.cnblogs.com/WarrenTang/archive/2008/05/29/1209726.html

Jsの练习-数组常用方法

1. join() 方法&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Comp…

新手学习笔记Spring AOP全自动编程

业务类 package oyb.service;public interface IUserService {public void add();public void delete(); } package oyb.service;public class UserServiceImpl implements IUserService {Overridepublic void add() {System.out.println("添加用户。。。。");}Overr…

Gradle入门:我们的第一个Java项目

这篇博客文章描述了如何使用Gradle编译和打包一个简单的Java项目。 我们的Java项目只有一个要求&#xff1a; 我们的构建脚本必须创建一个可执行的jar文件。 换句话说&#xff0c;我们必须能够使用以下命令运行程序&#xff1a; java -jar jarfile.jar让我们找出如何满足这一…

特征码弊端渐显 杀毒技术面临革命

一种观点认为&#xff0c;防病毒与安全供应商们在与网络罪犯们的战斗中正逐步失去主动。黑客们的网络爬虫正越来越多的偷偷潜入计算机&#xff0c;植入恶意程序&#xff0c;打开计算机发送远程攻击指令&#xff0c;并把它们变为僵尸网络的僵尸军团。 造成这个局面的根本原因在于…

《金字塔原理》读书笔记

第一篇 表达的逻辑 1.金字塔原理序文 人们希望达到的境界&#xff1a;想清楚、说明白、知道说什么、怎么说。 需要清楚3件事情&#xff1a; 谁是我的听众&#xff1f; 他们想听什么&#xff1f; 他们想怎么样听&#xff1f; 金字塔的基本原理 金字塔原理是一种重点突出、逻…

9 个鲜为人知的 Python 数据科学库

除了 pandas、scikit-learn 和 matplotlib&#xff0c;还要学习一些用 Python 进行数据科学的新技巧。Python 是一种令人惊叹的语言。事实上&#xff0c;它是世界上增长最快的编程语言之一。它一次又一次地证明了它在各个行业的开发者和数据科学者中的作用。Python 及其库的整个…

列出和过滤NIO.2中的目录内容

在Java 7发行之前&#xff0c;列出目录内容的领域并没有发生太多的事情。但是&#xff0c;由于NIO.2引入了一种新的方式来做到这一点&#xff0c;因此涵盖这一领域可能是值得的。 NIO.2的一大优点是能够在一个方法调用中立即使用列表和过滤。 这为与文件系统相关的大多数列表/筛…

Windows Mobile 编程 (Win32) - 获取设备能力

《Windows 程序设计》第五章重点讲述图形基础。首先一个示例代码是获取设备描述表信息。代码与Windows Mobile 编程 (Win32) - 输出文本中的代码类似。 #include <windows.h>#define NUMLINES ((int)(sizeof devcaps / sizeof devcaps[0]))struct {int iIndex;TCHAR …

Netty : writeAndFlush的线程安全及并发问题

使用Netty编程时&#xff0c;我们经常会从用户线程&#xff0c;而不是Netty线程池发起write操作&#xff0c;因为我们不能在netty的事件回调中做大量耗时操作。那么问题来了 – 1&#xff0c; writeAndFlush是线程安全的吗&#xff1f; 2&#xff0c; 是否使用了锁&#xff0c;…