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,一经查实,立即删除!

相关文章

CSS伪类的三种写法

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

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

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

生成器

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

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

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

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

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

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

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

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…

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

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

Spring4:具有Java 8 Date-Time API的@DateTimeFormat

在Spring 3.0中作为Formatter SPI的一部分引入的DateTimeFormat批注可用于解析和打印Web应用程序中的本地化字段值。 在Spring 4.0中&#xff0c; DateTimeFormat批注可以直接与Java 8 Date-Time API&#xff08; java.time &#xff09;一起使用。 在Spring中&#xff0c;可以…

JSF中run项目时候Tomcat8启动不了的一种方法

把另一个博客内容迁移到这 我的问题是Tomcat是可以启动的 但是run那个jsp的时候七月 10, 2016 3:14:54 下午 org.apache.tomcat.util.digester.SetPropertiesRule begin警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property source to org.eclipse…

elasticsearch_dsl.exceptions.ValidationException: You cannot write to a wildcard index.

elasticsearch_dsl.exceptions.ValidationException: You cannot write to a wildcard index. 这里是因为版本不匹配的问题 查看es版本方法如下&#xff1a; 查看elasticsearch包与elasticsearch-dsl版本方法&#xff08;pip list&#xff09;如下&#xff1a; 因为我的es是5.1…

在Java中对Singleton类进行双重检查锁定

Singleton类在Java开发人员中非常常见&#xff0c;但是它给初级开发人员带来了许多挑战。 他们面临的主要挑战之一是如何使Singleton保持为Singleton&#xff1f; 也就是说&#xff0c;无论出于何种原因&#xff0c;如何防止单个实例的多个实例。 对Singleton进行双重检查锁定是…

wstngfw中使用Viscosity连接OpenV-P-N服务器

wstngfw中使用Viscosity连接OpenV-P-N服务器 在本例中&#xff0c;将假设以下设置&#xff1a; 站点 A站点 B名称Beijing Office&#xff08;北京办公室&#xff09;名称Shenzheng Office&#xff08;深圳办公室&#xff09;WAN IP192.168.10.46WAN IP192.168.20.46LAN 子网192…

开张了!

今天开张了&#xff0c;试试看&#xff01; Code1using System; 2using System.Collections.Generic; 3using System.Text; 4 5namespace Model 6{ 7 public enum SiteType 8 { System,External,All}; 9 [Serializable]10 class SiteInfo11 {12 public i…

dubbo和zookeeper的关系

转载前言&#xff1a;网络上很多教程没有描述zookeeper和dubbo到底是什么关系、分别扮演了什么角色等信息&#xff0c;都是说一些似是而非的话&#xff0c;这里终于找到一篇文章&#xff0c;比较生动地描述了注册中心和微服务框架之间的关系&#xff0c;以及他们之间的合作分工…

Flink学习(二)Flink中的时间

摘自Apache Flink官网 最早的streaming 架构是storm的lambda架构 分为三个layer batch layerserving layerspeed layer一、在streaming中Flink支持的通知时间 Flink官网写了个了解streaming和各种时间的博客 https://www.oreilly.com/ideas/the-world-beyond-batch-streaming-1…

RSS阅读器使用:ROME,Spring MVC,嵌入式Jetty

在这篇文章中&#xff0c;我将展示一些创建Spring Web应用程序的准则&#xff0c;使用Jetty以及使用名为ROME的外部库运行RSS来运行它。 一般 我最近创建了一个示例Web应用程序&#xff0c;充当RSS阅读器。 我想检查ROME以阅读RSS。 我还想使用Spring容器和MVC创建最简单的视图…

HZOJ string

正解炸了…… 考试的时候想到了正解&#xff0c;非常高兴的打出来了线段树&#xff0c;又调了好长时间&#xff0c;对拍了一下发现除了非常大的点跑的有点慢外其他还行。因为复杂度算着有点高…… 最后正解死于常数太大……旁边的lyl用同样的算法拿了90分我却拿了个暴力的分40……

Unity3D入门其实很简单

在上次发布拙作后&#xff0c;有不少童鞋询问本人如何学习Unity3D。本人自知作为一名刚入门的菜鸟&#xff0c;实在没有资格谈论这么高大上的话题&#xff0c;生怕误导了各位。不过思来想去&#xff0c;决定还是写一些自己的经验&#xff0c;如果能给想要入门U3D的您一些启发&a…