apache camel_Apache Camel –从头开始开发应用程序(第1部分/第2部分)
apache camel
開始之前
前段時間,我寫了一篇關(guān)于Spring Integration的教程,以演示如何在受現(xiàn)實發(fā)票處理系統(tǒng)啟發(fā)的示例應(yīng)用程序中使用Spring Integration。 我對此非常滿意,因此我決定向您展示如何使用Apache Camel(Spring Integration的最大競爭對手)構(gòu)建完全相同的應(yīng)用程序。
我們將要構(gòu)建的應(yīng)用程序幾乎相同,因此本教程中的很多文字也將如此。 新部分將主要集中在Apache Camel及其用法上。
您可以逐步按照本教程操作,并從頭開始創(chuàng)建應(yīng)用程序,也可以繼續(xù)從github獲取代碼:在此處下載源: https : //github.com/vrto/apache-camel-invoices
請注意,還有更多方法來編寫駱駝“路線” – Java DSL,Spring XML,Scala DSL…在本教程中,我將使用Java DSL ,但對于那些感興趣的人–您也可以在此處找到通過Spring XML配置的相同項目。 。 無論您喜歡哪種方式,都該開始了!
發(fā)票處理申請書-功能說明
想象一下,您正在為某家公司工作,該公司會定期從各種承包商那里收到大量發(fā)票。 我們將建立一個能夠接收發(fā)票,過濾掉相關(guān)發(fā)票,創(chuàng)建付款(本地或國外)并將其發(fā)送到某些銀行服務(wù)的系統(tǒng)。 即使該系統(tǒng)非常幼稚,當(dāng)然也不適合企業(yè)使用,我們?nèi)詫L試以良好的可伸縮性,靈活性和分離的設(shè)計來構(gòu)建它。
Apache Camel是一個集成框架–這意味著它為要集成的復(fù)雜系統(tǒng)提供了有意義的抽象。
本教程有很多重要的概念需要理解。 讓我為您總結(jié)一下:
- 駱駝上下文 :將所有部分保持在一起的運行時系統(tǒng)。
- 消息 :基本實體–消息傳遞的核心原理。 它由標(biāo)題 , 正文和附件組成 。
- Exchange :消息的容器(對通過系統(tǒng)實際發(fā)送的內(nèi)容的抽象)。 它包含In消息,還可以包含Out消息。
- 路線 :處理器鏈。 如果您更喜歡“學(xué)術(shù)”解釋,則路由是一個圖形,其中“節(jié)點”由某個處理器表示,“線”由某個通道表示。
- 處理器 :使用/修改傳入的交換。 一個處理器的輸出連接到另一處理器的輸入。
- 端點 :建模通道末端。 使用URI進行配置。 例: file:data/inbox?delay=5000
- 組件 :端點工廠。 用前綴引用(jms:,file:等)。
如果您想了解有關(guān)駱駝核心概念的更多詳細(xì)信息,強烈建議您閱讀非常好的《 駱駝在行動》一書。
現(xiàn)在,我們對基本概念有了一些了解,讓我們看一下下面的圖片,它是系統(tǒng)的摘要,并遍歷了重要的部分:
在圖片上,您可以看到一條路線,該路線示出了我們的消息傳遞結(jié)構(gòu)和系統(tǒng)的核心組件-它們用紅色數(shù)字標(biāo)記。 讓我們來看一下(稍后我們將更詳細(xì)地介紹每個組件):
創(chuàng)建項目
到目前為止,您應(yīng)該對系統(tǒng)的功能以及其結(jié)構(gòu)有一個較高的概述。 在開始編碼之前,您將需要一個實際的Maven項目,并設(shè)置結(jié)構(gòu)和所需的依賴關(guān)系。 如果您熟悉Maven,請在下面查看pom.xml文件,否則,如果您想節(jié)省一些時間,歡迎使用我為您創(chuàng)建的項目模板: 下載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>apache-camel-invoices</groupId><artifactId>apache-camel-invoices</artifactId><version>1.0-SNAPSHOT</version><properties><camel-version>2.12.0</camel-version></properties><dependencies><dependency><groupId>org.apache.camel</groupId><artifactId>camel-core</artifactId><version>${camel-version}</version></dependency><dependency><groupId>org.apache.camel</groupId><artifactId>camel-spring</artifactId><version>${camel-version}</version></dependency><dependency><groupId>org.apache.camel</groupId><artifactId>camel-quartz</artifactId><version>2.9.5</version></dependency><dependency><groupId>org.apache.camel</groupId><artifactId>camel-test-spring</artifactId><version>${camel-version}</version><scope>test</scope></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.16</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.5</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>14.0.1</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><!--- uncomment when InvoicesApplication class will exist<plugin><groupId>org.codehaus.mojo</groupId><artifactId>exec-maven-plugin</artifactId><version>1.2.1</version><configuration><mainClass>com.vrtoonjava.invoices.InvoicesApplication</mainClass></configuration></plugin>--></plugins></build></project>自舉駱駝
在使用Apache Camel之前,我們需要對其進行一些引導(dǎo)。 首先,我們將創(chuàng)建包com.vrtoonjava.routes ,在其中放置路由配置。 其次,我們將創(chuàng)建InvoicesRouteBuilder類,該類將是配置路由的地方。 因此,像這樣創(chuàng)建類:
package com.vrtoonjava.routes;import org.apache.camel.builder.RouteBuilder; import org.springframework.stereotype.Component;@Component public class InvoicesRouteBuilder extends RouteBuilder {@Overridepublic void configure() throws Exception {//TODO configure route} }最后要做的是將Camel插入Spring(Camel將使用Spring作為bean的注冊表)。 將文件camel-config.xml添加到您的src / main / resources文件夾中,其中包含以下內(nèi)容:
<?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:camel="http://camel.apache.org/schema/spring"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"><camelContext xmlns="http://camel.apache.org/schema/spring"><routeBuilder ref="invoicesRouteBuilder"/></camelContext></beans>現(xiàn)在,讓我們更詳細(xì)地介紹系統(tǒng)的六個主要組件,并獲得實際的代碼。
1.發(fā)票網(wǎng)關(guān)
首先,讓我們看一下Invoice的代碼-這將是系統(tǒng)中的核心類之一。 我將使用com.vrtoonjava軟件包作為根軟件包,使用invoices和banking作為子軟件包:
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();}}想象一下,我們正在從另一個系統(tǒng)(數(shù)據(jù)庫,Web服務(wù)或其他系統(tǒng))獲取發(fā)票,但是我們不想將此部分耦合到集成層。 我們將為此使用網(wǎng)關(guān)組件。 Gateway引入了一個契約 ,該契約將客戶端代碼與集成層分離(在我們的示例中為Apache Camel依賴項)。 讓我們看一下InvoiceCollectorGateway的代碼:
package com.vrtoonjava.invoices;import java.util.Collection;/*** Defines a contract that decouples client from the Apache Camel framework.*/ public interface InvoiceCollectorGateway {void collectInvoices(Collection<Invoice> invoices);}我們定義了此接口,以使客戶僅依賴合同。 實際的實現(xiàn)將是特定于駱駝的,我們可以這樣創(chuàng)建它:
package com.vrtoonjava.invoices;import org.apache.camel.Produce; import org.apache.camel.ProducerTemplate; import org.springframework.stereotype.Component;import java.util.Collection;@Component public class CamelInvoiceCollectorGateway implements InvoiceCollectorGateway {@Produce(uri = "seda:newInvoicesChannel")ProducerTemplate producerTemplate;@Overridepublic void collectInvoices(Collection<Invoice> invoices) {producerTemplate.sendBody(invoices);}}注意@Produce批注。 此注釋告訴Camel,字段producerTemplate是端點seda:newInvoicesChannel 。 當(dāng)客戶端調(diào)用collectInvoices方法時,網(wǎng)關(guān)將向seda:newInvoicesChannel通道發(fā)送一條新消息(包含列表主體)。 這使客戶端與消息傳遞工具脫鉤,但是讓我們將結(jié)果放置到實際的消息傳遞通道中。
為什么選擇SEDA?
通常,在用Java構(gòu)建消息傳遞系統(tǒng)時,最終會使用像JMS這樣的東西,它提供了許多有用的功能,例如高可靠性或消息持久性。 在本教程中,我們將使用基于SEDA組件的更輕松的替代方法-它使我們能夠利用幾乎零配置的異步內(nèi)存中消息傳遞。
2.發(fā)票分割器
從網(wǎng)關(guān),我們向包含發(fā)票集合的系統(tǒng)發(fā)送一條大消息-換句話說,消息具有“ Collection類型的正文。 當(dāng)我們要單獨處理發(fā)票時,我們將從seda:newInvoicesChannel獲得結(jié)果,并使用分離器組件,該組件將創(chuàng)建多個消息。 這些新消息中的每一個都有一個“發(fā)票”類型的正文。 然后,我們將消息放置到新渠道– seda:singleInvoicesChannel 。 這就是我們定義拆分器的方式(將以下代碼添加到InvoicesRouteBuilder的configure方法中):
from("seda:newInvoicesChannel").log(LoggingLevel.INFO, "Invoices processing STARTED").split(body()).to("seda:singleInvoicesChannel");3.過濾一些發(fā)票
我們系統(tǒng)的業(yè)務(wù)用例要求我們僅自動處理發(fā)出少于$ 10,000的發(fā)票。 為此,我們將介紹一個過濾器組件。 我們將從seda:singleInvoicesChannel抓取消息,對它們應(yīng)用過濾邏輯,然后將匹配的結(jié)果寫入新的seda:filteredInvoicesChannel通道。 在Apache Camel中,您可以插入自己的包含過濾邏輯的謂詞 。 首先,讓我們定義這樣的謂詞(通過擴展Camel的org.apache.camel.Predicate ):
package com.vrtoonjava.invoices;import org.apache.camel.Exchange; import org.apache.camel.Predicate;public class LowEnoughAmountPredicate implements Predicate {public static final int LOW_ENOUGH_THRESHOLD = 10_000;@Overridepublic boolean matches(Exchange exchange) {Invoice invoice = exchange.getIn().getBody(Invoice.class);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;}}為了簡潔起見,我不在本教程中粘貼單元測試–但是,如果您有興趣, 請繼續(xù)下載github項目并親自查看測試 。
現(xiàn)在我們需要將此謂詞連接到我們的路由,因此將以下代碼添加到您的configure方法中:
from("seda:singleInvoicesChannel").filter(new LowEnoughAmountPredicate()).to("seda:filteredInvoicesChannel");4.路由發(fā)票
到目前為止,我們已經(jīng)拆分并過濾了一些發(fā)票。 現(xiàn)在是時候更仔細(xì)地檢查每個發(fā)票的內(nèi)容并決定是從當(dāng)前國家(本地)還是從另一個國家(外國)發(fā)行的發(fā)票了。 Apache Camel允許使用Java DSL中的choice()方法來定義基于內(nèi)容的路由器 。 我們甚至可以直接在Java DSL中訪問消息的主體并執(zhí)行一些簡單的評估。 將以下代碼添加到您的configure方法中(并注意我們?nèi)绾问褂?{body.isForeign}標(biāo)準(zhǔn)表達式來訪問body):
from("seda:filteredInvoicesChannel").choice().when().simple("${body.isForeign}").to("seda:foreignInvoicesChannel").otherwise().to("seda:localInvoicesChannel"); 我們將在本教程的第二部分中繼續(xù)開發(fā)此應(yīng)用程序。
翻譯自: https://www.javacodegeeks.com/2013/10/apache-camel-developing-application-from-the-scratch-part-1-2.html
apache camel
總結(jié)
以上是生活随笔為你收集整理的apache camel_Apache Camel –从头开始开发应用程序(第1部分/第2部分)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分析师绘制 Top30 GenAI 各国
- 下一篇: 小鸡词典告新浪微博“抄袭案”一审败诉,创