javascript
Spring集成–从头开始应用程序,第1部分
開始之前
 在本教程中,您將學(xué)習(xí)什么是Spring Integration ,如何使用它以及有助于解決哪些問題。 我們將從頭開始構(gòu)建一個(gè)示例應(yīng)用程序,并演示Spring Integration的一些核心組件。 如果您不熟悉Spring,請(qǐng)查看我編寫的另一本有關(guān)Spring的教程- 我們可以一起做一些Spring嗎? 還要注意,您不需要任何特殊的工具,但是您可以使用IntelliJ IDEA或Spring Tool Suite來獲得構(gòu)建Spring Integration應(yīng)用程序的最佳體驗(yàn)(使用STS可以獲得一些精美的圖表)。 您可以按照本教程逐步操作并自己從頭開始創(chuàng)建應(yīng)用程序,也可以繼續(xù)從github獲取代碼: 
此處下載資源: https : //github.com/vrto/spring-integration-invoices 
無論您喜歡哪種方式,都該開始了!
發(fā)票處理申請(qǐng)書-功能說明
想象一下,您在某家公司工作,該公司會(huì)定期從各種承包商那里收到大量發(fā)票。 我們將建立一個(gè)能夠接收發(fā)票,過濾掉相關(guān)發(fā)票,創(chuàng)建付款(本地或國(guó)外)并將其發(fā)送到某些銀行服務(wù)的系統(tǒng)。 即使該系統(tǒng)非常幼稚,當(dāng)然也不適合企業(yè)使用,我們?nèi)詫L試在頭腦中以良好的可伸縮性,靈活性和分離的設(shè)計(jì)來構(gòu)建它。
 在繼續(xù)之前,您必須意識(shí)到一件事:Spring Integration是(不僅但主要是)關(guān)于消息傳遞的 。 Spring Integration基本上是嵌入式企業(yè)服務(wù)總線 ,可讓您無縫地將業(yè)務(wù)邏輯連接到消息傳遞通道。 可以通過編程方式(通過Spring Integration API)或自動(dòng)(通過框架本身–更高級(jí)別的解耦)來處理消息。 消息是跨渠道傳播的東西。 消息具有標(biāo)題和有效負(fù)載 –在我們的示例中,它們將是實(shí)際相關(guān)的內(nèi)容(域類)。 讓我們看一下下面的圖片,它是系統(tǒng)的摘要,并遍歷了重要的部分: 
 
 
在圖片上,您可以看到一個(gè)集成圖,該圖說明了我們的消息傳遞結(jié)構(gòu)和系統(tǒng)的核心組件-它們用紅色數(shù)字標(biāo)記。 讓我們來看一下(稍后我們將更詳細(xì)地介紹每個(gè)組件):
創(chuàng)建項(xiàng)目
到目前為止,您應(yīng)該對(duì)系統(tǒng)的功能以及其結(jié)構(gòu)有一個(gè)較高的概述。 在開始編碼之前,您將需要一個(gè)實(shí)際的Maven項(xiàng)目,并設(shè)置結(jié)構(gòu)和所需的依賴關(guān)系。 如果您熟悉Maven,請(qǐng)參見下面的pom.xml文件,否則,如果您想節(jié)省一些時(shí)間,歡迎使用我為您創(chuàng)建的項(xiàng)目模板: 下載Maven項(xiàng)目模板 。
<?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>現(xiàn)在,讓我們更詳細(xì)地介紹系統(tǒng)的六個(gè)主要組件,并獲得實(shí)際的代碼。
1.發(fā)票網(wǎng)關(guān)
首先,讓我們看一下Invoice的代碼-這將是系統(tǒng)中的核心類之一。 我將使用com.vrtoonjava軟件包作為根軟件包,使用發(fā)票和銀行業(yè)務(wù)作為子軟件包:
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();}}想象一下,我們從另一個(gè)系統(tǒng)(數(shù)據(jù)庫(kù),Web服務(wù)或其他系統(tǒng))獲取發(fā)票,但是我們不想將此部分耦合到集成層。 我們將為此使用網(wǎng)關(guān)組件。 Gateway引入了一個(gè)協(xié)議 ,該協(xié)議將客戶端代碼與集成層分離(在我們的案例中為Spring Integration依賴項(xiàng))。 讓我們看一下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);}現(xiàn)在,要實(shí)際使用Spring Integration,我們需要?jiǎng)?chuàng)建一個(gè)標(biāo)準(zhǔn)的Spring配置文件并使用Spring Integration名稱空間。 首先,這是invoices-int-schema.xml文件。 將其放入src / main / resources 。 請(qǐng)注意,我們已經(jīng)定義了一個(gè)logging-channel-adapter ,這是一個(gè)特殊的通道,我們將從記錄器發(fā)送消息。 我們還使用竊聽 –您可以將其視為一種全局?jǐn)r截器,它將向日志記錄器通道發(fā)送與日志記錄相關(guān)的消息。
<?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>現(xiàn)在回到我們的網(wǎng)關(guān)。 我們已經(jīng)定義了一個(gè)網(wǎng)關(guān)接口–這是客戶端將使用的依賴項(xiàng)。 當(dāng)客戶端調(diào)用collectInvoices方法時(shí),網(wǎng)關(guān)將向newInvoicesChannel通道發(fā)送一條新消息(包含List負(fù)載)。 這使客戶端與消息傳遞工具脫鉤,但是讓我們將結(jié)果放置到實(shí)際的消息傳遞通道中。 要配置網(wǎng)關(guān),請(qǐng)將以下代碼添加到集成模式配置中:
<int:channel id = 'newInvoicesChannel' /><int:gateway id='invoicesGateway'service-interface='com.vrtoonjava.invoices.InvoiceCollectorGateway'><int:method name='collectInvoices' request-channel='newInvoicesChannel' /> </int:gateway>2.發(fā)票分割器
從網(wǎng)關(guān),我們正在向包含發(fā)票集合的系統(tǒng)發(fā)送一條大消息,換句話說,消息具有“收集”類型的有效負(fù)載。 當(dāng)我們要單獨(dú)處理發(fā)票時(shí),我們將從newInvoicesChannel獲得結(jié)果并使用分離器組件,該組件將創(chuàng)建多條消息。 這些新消息中的每一個(gè)將具有發(fā)票類型的有效負(fù)載。 然后,我們將消息放置到新渠道– singleInvoicesChannel 。 我們將使用Spring Integration提供的默認(rèn)拆分器(默認(rèn)情況下,Spring Integration使用DefaultMessageSplitter來實(shí)現(xiàn)我們想要的功能)。 這是我們定義分離器的方式:
<int:splitterinput-channel='newInvoicesChannel'output-channel='singleInvoicesChannel' /><int:channel id = 'singleInvoicesChannel' />3.過濾一些發(fā)票
我們系統(tǒng)的業(yè)務(wù)用例要求我們僅自動(dòng)處理發(fā)出少于$ 10,000的發(fā)票。 為此,我們將介紹一個(gè)過濾器組件。 我們將從singleInvoicesChannel抓取消息,對(duì)它們應(yīng)用過濾邏輯,然后將匹配的結(jié)果寫入新的filterInvoicesChannel通道。 首先,讓我們創(chuàng)建一個(gè)標(biāo)準(zhǔn)的Java類,其中將包含針對(duì)單個(gè)發(fā)票的過濾邏輯。 請(qǐng)注意,我們使用@Component注釋(這使其成為標(biāo)準(zhǔn)的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;}}請(qǐng)注意,這是一個(gè)標(biāo)準(zhǔn)的POJO,我們可以輕松對(duì)其進(jìn)行單元測(cè)試 ! 就像我之前說過的那樣,Spring Integration并未將我們與其消息傳遞工具緊密耦合。 為了簡(jiǎn)潔起見,我不在本教程中粘貼單元測(cè)試–但是,如果您有興趣, 請(qǐng)繼續(xù)下載github項(xiàng)目并親自查看測(cè)試 。
讓我們?yōu)橄鬟f層指定輸入/輸出通道,并將過濾器掛入。將以下代碼添加到集成模式配置中:
<int:filterinput-channel='singleInvoicesChannel'output-channel='filteredInvoicesChannel'ref='invoiceFilter' /><int:channel id = 'filteredInvoicesChannel' />4.路由發(fā)票
到目前為止,我們已經(jīng)拆分并過濾了一些發(fā)票。 現(xiàn)在是時(shí)候更仔細(xì)地檢查每個(gè)發(fā)票的內(nèi)容并決定是從當(dāng)前國(guó)家(本地)還是從另一個(gè)國(guó)家(外國(guó))發(fā)行的發(fā)票了。 為此,我們可以像以前一樣處理并將自定義類用于路由邏輯。 我們(出于演示目的)現(xiàn)在將采用另一種方法-我們將使用Spring Expression Language(SpEL)來完全聲明性地使用和處理路由。 還記得發(fā)票類上的isForeign方法嗎? 我們可以在路由器聲明中使用SpEL直接調(diào)用它(通過使用selector-expression屬性)! 路由器將查看有效負(fù)載,評(píng)估它是國(guó)外發(fā)票還是本地發(fā)票,并將其轉(zhuǎn)發(fā)到相應(yīng)的渠道:
<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' /> 我們將在本教程的第二部分中繼續(xù)開發(fā)此應(yīng)用程序。 
參考: Spring Integration –從頭開始的應(yīng)用程序,來自 vrtoonjava博客的JCG合作伙伴 Michal Vrtiak的第1部分 。
翻譯自: https://www.javacodegeeks.com/2013/03/spring-integration-application-from-scratch-part-1.html
總結(jié)
以上是生活随笔為你收集整理的Spring集成–从头开始应用程序,第1部分的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 任正非:华为要建立高端人才储备库
 - 下一篇: 广州:将新建世界领先智能汽车示范园区,本