开始之前

在本教程中,您将学习什么是Spring Integration ,如何使用它以及有助于解决哪些问题。 我们将从头开始构建一个示例应用程序,并演示Spring Integration的一些核心组件。 如果您不熟悉Spring,请查看我编写的另一本有关Spring的教程- 我们可以一起做一些Spring吗? 还要注意,您不需要任何特殊的工具,但是您可以使用IntelliJ IDEA或Spring Tool Suite来获得构建Spring Integration应用程序的最佳体验(使用STS可以获得一些精美的图表)。 您可以按照本教程逐步操作并自己从头开始创建应用程序,也可以继续从github获取代码:
此处下载资源: https : //github.com/vrto/spring-integration-invoices

无论您喜欢哪种方式,都该开始了!

发票处理申请书-功能说明

想象一下,您在某家公司工作,该公司会定期从各种承包商那里收到大量发票。 我们将建立一个能够接收发票,过滤掉相关发票,创建付款(本地或国外)并将其发送到某些银行服务的系统。 即使该系统非常幼稚,当然也不适合企业使用,我们仍将尝试在头脑中以良好的可伸缩性,灵活性和分离的设计来构建它。

在继续之前,您必须意识到一件事:Spring Integration是(不仅但主要是)关于消息传递的 。 Spring Integration基本上是嵌入式企业服务总线 ,可让您无缝地将业务逻辑连接到消息传递通道。 可以通过编程方式(通过Spring Integration API)或自动(通过框架本身–更高级别的解耦)来处理消息。 消息是跨渠道传播的东西。 消息具有标题和有效负载 –在我们的示例中,它们将是实际相关的内容(域类)。 让我们看一下下面的图片,它是系统的摘要,并遍历了重要的部分:

在图片上,您可以看到一个集成图,该图说明了我们的消息传递结构和系统的核心组件-它们用红色数字标记。 让我们来看一下(稍后我们将更详细地介绍每个组件):

  1. 发票网关 –这是我们放置新发票的地方,以便它们可以进入消息传递层
  2. 拆分器 -该系统旨在接受发票的集合,但是我们将需要单独处理每个发票。 更具体地说,具有“收集”类型有效负载的消息将被拆分为多个消息,其中每个消息将具有单独的发票作为有效负载。
  3. 筛选器 -我们的系统旨在仅自动处理开具少于$ 10,000的那些发票
  4. 路由器 -有些发票使用IBAN帐号,我们有两个不同的帐户-一个用于本地交易,一个用于国外交易。 路由器组件的工作是将带有发票的消息发送到正确的通道-无论是本地发票还是国外发票。
  5. 变形金刚 –当我们在系统中接受发票时,我们的银行API可以与其他类型一起使用–付款。 转换器组件的工作是根据提供的逻辑获取一些消息并将其转换为另一条消息。 我们希望将原始消息(发票)的有效负载转换为新的有效负载-付款。
  6. Banking Service Activator –处理发票并生成一些实际付款后,我们准备与外部银行系统进行对话。 我们已经公开了此类系统的服务,当携带付款的消息进入正确的(银行)渠道时,我们想激活一些逻辑–将付款传递给银行,然后让银行进行进一步处理。

创建项目

到目前为止,您应该对系统的功能以及其结构有一个较高的概述。 在开始编码之前,您将需要一个实际的Maven项目,并设置结构和所需的依赖关系。 如果您熟悉Maven,请参见下面的pom.xml文件,否则,如果您想节省一些时间,欢迎使用我为您创建的项目模板: 下载Maven项目模板 。

<?xml version='1.0' encoding='UTF-8'?>
<project xmlns='http://maven.apache.org/POM/4.0.0'xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd'><modelVersion>4.0.0</modelVersion><groupId>spring-integration-invoices</groupId><artifactId>spring-integration-invoices</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>3.2.1.RELEASE</version></dependency><dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-core</artifactId><version>2.2.1.RELEASE</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.16</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>13.0.1</version></dependency><dependency><groupId>org.testng</groupId><artifactId>testng</artifactId><version>6.5.2</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.7</source><target>1.7</target></configuration></plugin></plugins></build></project>

现在,让我们更详细地介绍系统的六个主要组件,并获得实际的代码。

1.发票网关

首先,让我们看一下Invoice的代码-这将是系统中的核心类之一。 我将使用com.vrtoonjava软件包作为根软件包,使用发票银行业务作为子软件包:

package com.vrtoonjava.invoices;import com.google.common.base.Objects;import java.math.BigDecimal;public class Invoice {private final String iban;private final String address;private final String account;private final BigDecimal dollars;public Invoice(String iban, String address, String account, BigDecimal dollars) {this.iban = iban;this.address = address;this.account = account;this.dollars = dollars;}public boolean isForeign() {return null != iban && !iban.isEmpty();}public String getAddress() {return address;}public String getAccount() {return account;}public BigDecimal getDollars() {return dollars;}public String getIban() {return iban;}@Overridepublic String toString() {return Objects.toStringHelper(this).add('iban', iban).add('address', address).add('account', account).add('dollars', dollars).toString();}}

想象一下,我们从另一个系统(数据库,Web服务或其他系统)获取发票,但是我们不想将此部分耦合到集成层。 我们将为此使用网关组件。 Gateway引入了一个协议 ,该协议将客户端代码与集成层分离(在我们的案例中为Spring Integration依赖项)。 让我们看一下InvoiceCollectorGateway的代码:

package com.vrtoonjava.invoices;import java.util.Collection;/*** Defines a contract that decouples client from the Spring Integration framework.*/
public interface InvoiceCollectorGateway {void collectInvoices(Collection<Invoice> invoices);}

现在,要实际使用Spring Integration,我们需要创建一个标准的Spring配置文件并使用Spring Integration名称空间。 首先,这是invoices-int-schema.xml文件。 将其放入src / main / resources 。 请注意,我们已经定义了一个logging-channel-adapter ,这是一个特殊的通道,我们将从记录器发送消息。 我们还使用窃听 –您可以将其视为一种全局拦截器,它将向日志记录器通道发送与日志记录相关的消息。

<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns = 'http://www.springframework.org/schema/beans'xmlns:xsi = 'http://www.w3.org/2001/XMLSchema-instance'xmlns:int = 'http://www.springframework.org/schema/integration'xsi:schemaLocation = 'http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd'><!-- intercept and log every message --><int:logging-channel-adapter id='logger' level='DEBUG' /><int:wire-tap channel = 'logger' />
</beans>

现在回到我们的网关。 我们已经定义了一个网关接口–这是客户端将使用的依赖项。 当客户端调用collectInvoices方法时,网关将向newInvoicesChannel通道发送一条新消息(包含List负载)。 这使客户端与消息传递工具脱钩,但是让我们将结果放置到实际的消息传递通道中。 要配置网关,请将以下代码添加到集成模式配置中:

<int:channel id = 'newInvoicesChannel' /><int:gateway id='invoicesGateway'service-interface='com.vrtoonjava.invoices.InvoiceCollectorGateway'><int:method name='collectInvoices' request-channel='newInvoicesChannel' />
</int:gateway>

2.发票分割器

从网关,我们正在向包含发票集合的系统发送一条大消息,换句话说,消息具有“收集”类型的有效负载。 当我们要单独处理发票时,我们将从newInvoicesChannel获得结果并使用分离器组件,该组件将创建多条消息。 这些新消息中的每一个将具有发票类型的有效负载。 然后,我们将消息放置到新渠道– singleInvoicesChannel 。 我们将使用Spring Integration提供的默认拆分器(默认情况下,Spring Integration使用DefaultMessageSplitter来实现我们想要的功能)。 这是我们定义分离器的方式:

<int:splitterinput-channel='newInvoicesChannel'output-channel='singleInvoicesChannel' /><int:channel id = 'singleInvoicesChannel' />

3.过滤一些发票

我们系统的业务用例要求我们仅自动处理发出少于$ 10,000的发票。 为此,我们将介绍一个过滤器组件。 我们将从singleInvoicesChannel抓取消息,对它们应用过滤逻辑,然后将匹配的结果写入新的filterInvoicesChannel通道。 首先,让我们创建一个标准的Java类,其中将包含针对单个发票的过滤逻辑。 请注意,我们使用@Component注释(这使其成为标准的Spring bean),并使用@Filter注释注释过滤方法-这将告诉Spring Integration使用此方法过滤逻辑:

package com.vrtoonjava.invoices;import org.springframework.integration.annotation.Filter;
import org.springframework.stereotype.Component;@Component
public class InvoiceFilter {public static final int LOW_ENOUGH_THRESHOLD = 10_000;@Filterpublic boolean accept(Invoice invoice) {boolean lowEnough = invoice.getDollars().intValue() < LOW_ENOUGH_THRESHOLD;System.out.println('Amount of $' + invoice.getDollars()+ (lowEnough ? ' can' : ' can not') + ' be automatically processed by system');return lowEnough;}}

请注意,这是一个标准的POJO,我们可以轻松对其进行单元测试 ! 就像我之前说过的那样,Spring Integration并未将我们与其消息传递工具紧密耦合。 为了简洁起见,我不在本教程中粘贴单元测试–但是,如果您有兴趣, 请继续下载github项目并亲自查看测试

让我们为消息传递层指定输入/输出通道,并将过滤器挂入。将以下代码添加到集成模式配置中:

<int:filterinput-channel='singleInvoicesChannel'output-channel='filteredInvoicesChannel'ref='invoiceFilter' /><int:channel id = 'filteredInvoicesChannel' />

4.路由发票

到目前为止,我们已经拆分并过滤了一些发票。 现在是时候更仔细地检查每个发票的内容并决定是从当前国家(本地)还是从另一个国家(外国)发行的发票了。 为此,我们可以像以前一样处理并将自定义类用于路由逻辑。 我们(出于演示目的)现在将采用另一种方法-我们将使用Spring Expression Language(SpEL)来完全声明性地使用和处理路由。 还记得发票类上的isForeign方法吗? 我们可以在路由器声明中使用SpEL直接调用它(通过使用selector-expression属性)! 路由器将查看有效负载,评估它是国外发票还是本地发票,并将其转发到相应的渠道:

<int:recipient-list-router input-channel='filteredInvoicesChannel'><int:recipient channel = 'foreignTransactions' selector-expression='payload.foreign' /><int:recipient channel = 'localTransactions' selector-expression='!payload.foreign' />
</int:recipient-list-router><int:channel id = 'foreignTransactions' />
<int:channel id = 'localTransactions' />

我们将在本教程的第二部分中继续开发此应用程序。

参考: Spring Integration –从头开始的应用程序,来自 vrtoonjava博客的JCG合作伙伴 Michal Vrtiak的第1部分 。

翻译自: https://www.javacodegeeks.com/2013/03/spring-integration-application-from-scratch-part-1.html

Spring集成–从头开始应用程序,第1部分相关推荐

  1. Spring集成–从头开始应用程序,第2部分

    这是本教程的第二部分,我们将使用Spring Integration创建发票处理应用程序. 如果您错过了它,一定要看一下第一部分 . 以前,我们已经定义了系统的功能要求,创建了网关,分离器,过滤器和路 ...

  2. spring集成jndi_Spring应用程序与JNDI连接池的集成测试

    spring集成jndi 我们都知道,无论何时连接到数据库,都需要使用连接池. 所有使用JDBC 4类的现代驱动程序都支持它. 在本文中,我们将概述Spring应用程序中的连接池,以及如何在非JEE环 ...

  3. 将Spring集成到旧版应用程序中

    所有Spring开发人员喜欢做的事情之一就是将Spring塞入他们正在工作的任何应用程序中–这是我生活中的罪恶感之一:您看到一些代码,认为它是垃圾,因为它包含几个众所周知的反模式,然后想想如果这个应用 ...

  4. apache camel_Apache Camel –从头开始开发应用程序(第1部分/第2部分)

    apache camel 开始之前 前段时间,我写了一篇关于Spring Integration的教程,以演示如何在受现实发票处理系统启发的示例应用程序中使用Spring Integration. 我 ...

  5. Spring集成和Web服务

    本文是我们名为" Spring Integration for EAI "的学院课程的一部分. 在本课程中,向您介绍了企业应用程序集成模式以及Spring Integration如 ...

  6. gwt格式_使用Spring Security保护GWT应用程序的安全

    gwt格式 在本教程中,我们将看到如何将GWT与Spring的安全模块(即Spring Security)集成. 我们将看到如何保护GWT入口点,如何检索用户的凭据以及如何记录各种身份验证事件. 此外 ...

  7. Apache Camel –从头开始开发应用程序(第1部分/第2部分)

    开始之前 前一段时间,我写了一篇关于Spring Integration的教程,以演示如何在受现实发票处理系统启发的示例应用程序中使用Spring Integration. 我对此非常满意,因此我决定 ...

  8. 使用Spring Security保护GWT应用程序

    在本教程中,我们将看到如何将GWT与Spring的安全模块(即Spring Security)集成在一起. 我们将看到如何保护GWT入口点,如何检索用户的凭据以及如何记录各种身份验证事件. 此外,我们 ...

  9. spring集成kafka,以及常见错误解决

    spring集成kafka,以及常见错误解决 一.配置kafka 1.引入jar包 <!--Kafka和spring集成的支持类库,spring和kafka通信监听--><!-- h ...

最新文章

  1. 招商银行行长田惠宇:疫情对信用卡业务造成影响最大,40%催收产能在武汉
  2. iccar conference oral presentation
  3. 安卓APP_ 控件(2)—— Button
  4. Go_笔试题记录-指针与值类型实现接口的区别
  5. bootstrap validator 提供了哪些验证函数
  6. python 实现数据化大屏_基于Python实现交互式数据可视化的工具(用于Web)
  7. Apache Commons BeanUtils包学习 2 -beanutils PropertyUtils bean
  8. SaaSpace:最好的免费网络安全工具
  9. Java widget xui_XUI使用总结
  10. oracle10g迁移到11g配置,Windows下Oracle10g32位迁移到11g64位
  11. 获取百度地图开发平台的key
  12. 字符在计算机中的存储
  13. phpcmsV9 全站搜索功能如何实现
  14. scratch编程密室逃脱
  15. image-rendering 像素化图像像素(实验中)
  16. tm4c123gxl库函数调包侠养成(一)——————基本系统时钟与delay函数
  17. 【理论-Cisco】策略路由PBR
  18. 武汉意向岗位(二)——中国农业银行研发中心
  19. 数据分析思维(五)|逻辑树思维
  20. Excel求解运输问题——以福斯特公司问题为例

热门文章

  1. react 线程_React式服务中的线程本地状态可用性
  2. java8日期转时间戳_Java 8日期和时间
  3. prima evb_用Priam设置Cassandra
  4. mysql 死锁监视器_并发基础知识:死锁和对象监视器
  5. tomcat与tomee_Apache TomEE(和Tomcat)的自签名证书
  6. spring 多租户_使用Spring Security的多租户应用程序的无状态会话
  7. Spring @RequestParam批注
  8. Apache Camel 3 –骆驼核心vs骆驼核心引擎(较小的核心)
  9. 垃圾收集算法,垃圾收集器_垃圾收集器准则和提示
  10. intent隐式和显式_Neo4j:使隐式关系成为显式和双向关系