日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

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

發布時間:2023/12/3 javascript 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring集成–从头开始应用程序,第2部分 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是本教程的第二部分,我們將使用Spring Integration創建發票處理應用程序。 如果您錯過了它,一定要看一下第一部分 。 以前,我們已經定義了系統的功能要求,創建了網關,分離器,過濾器和路由器組件。 讓我們繼續創建一個轉換器。

5.將發票轉換為付款

現在,我們已經成功地從系統中過濾掉了“過于昂貴”的發票(它們可能需要人工檢查等)。 重要的是,我們現在可以收取發票并從中產生付款。 首先,讓我們將Payment類添加到銀行
包:

package com.vrtoonjava.banking;import com.google.common.base.Objects;import java.math.BigDecimal;public class Payment {private final String senderAccount;private final String receiverAccount;private final BigDecimal dollars;public Payment(String senderAccount, String receiverAccount, BigDecimal dollars) {this.senderAccount = senderAccount;this.receiverAccount = receiverAccount;this.dollars = dollars;}public String getSenderAccount() {return senderAccount;}public String getReceiverAccount() {return receiverAccount;}public BigDecimal getDollars() {return dollars;}@Overridepublic String toString() {return Objects.toStringHelper(this).add('senderAccount', senderAccount).add('receiverAccount', receiverAccount).add('dollars', dollars).toString();}}

因為我們將有兩種方法(從本地和國外發票)創建付款,所以我們定義一個用于創建付款的通用合同(界面)。 將界面PaymentCreator放入銀行業務包:

package com.vrtoonjava.banking;import com.vrtoonjava.invoices.Invoice;/*** Creates payment for bank from the invoice.* Real world implementation might do some I/O expensive stuff.*/ public interface PaymentCreator {Payment createPayment(Invoice invoice) throws PaymentException;}

從技術上講,這是一個簡單的參數化工廠。 請注意,它將引發PaymentException 。 稍后我們將進行異常處理,但這是簡單的PaymentException的代碼:

package com.vrtoonjava.banking;public class PaymentException extends Exception {public PaymentException(String message) {super(message);}}

現在,我們可以將兩個實現添加到發票包中了。 首先,讓我們創建LocalPaymentCreator類:

package com.vrtoonjava.invoices;import com.vrtoonjava.banking.Payment; import com.vrtoonjava.banking.PaymentCreator; import com.vrtoonjava.banking.PaymentException; import org.springframework.integration.annotation.Transformer; import org.springframework.stereotype.Component;@Component public class LocalPaymentCreator implements PaymentCreator {// hard coded account value for demo purposesprivate static final String CURRENT_LOCAL_ACC = 'current-local-acc';@Override@Transformerpublic Payment createPayment(Invoice invoice) throws PaymentException {if (null == invoice.getAccount()) {throw new PaymentException('Account can not be empty when creating local payment!');}return new Payment(CURRENT_LOCAL_ACC, invoice.getAccount(), invoice.getDollars());}}

另一個創建者將是ForeignPaymentCreator ,它具有相當簡單的實現:

package com.vrtoonjava.invoices;import com.vrtoonjava.banking.Payment; import com.vrtoonjava.banking.PaymentCreator; import com.vrtoonjava.banking.PaymentException; import org.springframework.integration.annotation.Transformer; import org.springframework.stereotype.Component;@Component public class ForeignPaymentCreator implements PaymentCreator {// hard coded account value for demo purposesprivate static final String CURRENT_IBAN_ACC = 'current-iban-acc';@Override@Transformerpublic Payment createPayment(Invoice invoice) throws PaymentException {if (null == invoice.getIban()) {throw new PaymentException('IBAN mustn't be null when creating foreign payment!');}return new Payment(CURRENT_IBAN_ACC, invoice.getIban(), invoice.getDollars());}}

有關創建者的有趣部分是@Transformer批注。 這是與@Filter注釋一起使用的概念類似–只是這次我們告訴Spring Integration它應該使用此方法進行有效負載轉換邏輯。 無論哪種方式,我們都將使用外部或本地轉換器,因此新消息將在BankingChannel通道中結束。 讓我們在架構文件中定義這些新的轉換器:

<int:transformerinput-channel='localTransactions'output-channel='bankingChannel'ref='localPaymentCreator' /><int:transformerinput-channel='foreignTransactions'output-channel='bankingChannel'ref='foreignPaymentCreator' /><int:channel id = 'bankingChannel'><int:queue capacity='1000' /> </int:channel>

6.將付款轉到銀行服務(服務激活器)

付款已準備就緒,包含付款的消息正在bankingChannel中等待。 該流程的最后一步是使用Service Activator組件。 它的工作方式很簡單-當新消息出現在通道中時,Spring Integration會調用Service Activator組件中指定的邏輯。 因此,當新的付款出現在bankingChannel中時,我們希望將其傳遞給銀行服務。
為此,我們首先需要查看銀行服務合同。 因此,將BankingService接口添加到銀行程序包中(在現實世界中,它可能駐留在某些外部模塊中):

package com.vrtoonjava.banking;/*** Contract for communication with bank.*/ public interface BankingService {void pay(Payment payment) throws PaymentException;}

現在,我們將需要BankingService的實際實現。 同樣,實現不太可能駐留在我們的項目中(它可能是遠程公開的服務),但是至少出于教程目的,讓我們創建一些模擬實現。 將MockBankingService類添加到銀行業務包:

package com.vrtoonjava.banking;import org.springframework.stereotype.Service;import java.util.Random;/*** Mock service that simulates some banking behavior.* In real world, we might use some web service or a proxy of real service.*/ @Service public class MockBankingService implements BankingService {private final Random rand = new Random();@Overridepublic void pay(Payment payment) throws PaymentException {if (rand.nextDouble() > 0.9) {throw new PaymentException('Banking services are offline, try again later!');}System.out.println('Processing payment ' + payment);}}

模擬實施會在某些隨機情況下(約10%)造成失敗。 當然,為了實現更好的解耦,我們不會直接使用它,而是將根據自定義組件在合同(接口)上創建依賴關系。 讓我們現在將PaymentProcessor類添加到發票包中:

package com.vrtoonjava.invoices;import com.vrtoonjava.banking.BankingService; import com.vrtoonjava.banking.Payment; import com.vrtoonjava.banking.PaymentException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.integration.annotation.ServiceActivator; import org.springframework.stereotype.Component;/*** Endpoint that picks Payments from the system and dispatches them to the* service provided by bank.*/ @Component public class PaymentProcessor {@AutowiredBankingService bankingService;@ServiceActivatorpublic void processPayment(Payment payment) throws PaymentException {bankingService.pay(payment);}}

再次-注意@ServiceActivator批注。 這意味著當服務激活器組件出現在游戲中時,Spring Integration應該調用相應的方法。 要使用服務激活器,我們需要將其添加到集成模式中:

<int:service-activator input-channel='bankingChannel' ref='paymentProcessor'><int:poller fixed-rate='500' error-channel='failedPaymentsChannel' /> </int:service-activator><int:channel id = 'failedPaymentsChannel' />

請注意,我們正在定義固定速率屬性,這意味著將每半秒調用一次激活器(如果BankingChannel中存在某些消息)。 我們還定義了錯誤通道屬性,但是我們很快就會到達那里。

錯誤處理

消息傳遞系統的最大挑戰之一是正確識別和處理錯誤情況。 Spring Integration提供了一種稱為“錯誤通道”的技術,我們可以(顯然)從系統發送錯誤消息。 錯誤通道只是另一個通道,當此通道中出現錯誤消息時,我們可以采取適當的措施。 在實際的應用程序中,我們可能會尋求一些重試邏輯或專業報告,在我們的示例教程中,我們只會打印出錯誤原因。 在上一個組件(服務激活器)中,我們指定了error-channel屬性來引用failedPaymentsChannel 。 當消息到達此通道時,我們將調用另一個服務激活器并打印出錯誤。 這是FailedPaymentHandler服務激活器的實現:

package com.vrtoonjava.invoices;import org.springframework.integration.annotation.ServiceActivator; import org.springframework.stereotype.Component;@Component public class FailedPaymentHandler {@ServiceActivatorpublic void handleFailedPayment(Exception e) {System.out.println('Payment failed: ' + e);// now the system should do something reasonable, like retrying the payment// omitted for the tutorial purposes}}

然后像往常一樣將其連接到集成模式:

<int:service-activatorinput-channel='failedPaymentsChannel'ref='failedPaymentHandler' />

運行整個事情

現在,我們將創建一個作業(它將以固定的速率)將新發票發送到系統。 它只是利用Spring的@Scheduled注釋的標準Spring bean。 因此,我們向項目添加一個新類– InvoicesJob :

package com.vrtoonjava.invoices;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component;import java.util.ArrayList; import java.util.Collection; import java.util.List;/*** Job that every n-seconds generates invoices and sends them to the system.* In real world this might be endpoint receiving invoices from another system.*/ @Component public class InvoicesJob {private int limit = 10; // default value, configurable@AutowiredInvoiceCollectorGateway invoiceCollector;@AutowiredInvoiceGenerator invoiceGenerator;@Scheduled(fixedRate = 4000)public void scheduleInvoicesHandling() {Collection<Invoice> invoices = generateInvoices(limit);System.out.println('\n===========> Sending ' + invoices.size() + ' invoices to the system');invoiceCollector.collectInvoices(invoices);}// configurable from Injectorpublic void setLimit(int limit) {this.limit = limit;}private Collection<Invoice> generateInvoices(int limit) {List<Invoice> invoices = new ArrayList<>();for (int i = 0; i < limit; i++) {invoices.add(invoiceGenerator.nextInvoice());}return invoices;}}

Job會調用(每4秒一次) InvoicesGenerator并將發票轉發到Gateway(我們了解的第一個組件)。 為了使其工作,我們還需要InvoicesGenerator類:

package com.vrtoonjava.invoices;import org.springframework.stereotype.Component;import java.math.BigDecimal; import java.util.Random;/*** Utility class for generating invoices.*/ @Component public class InvoiceGenerator {private Random rand = new Random();public Invoice nextInvoice() {return new Invoice(rand.nextBoolean() ? iban() : null, address(), account(), dollars());}private BigDecimal dollars() {return new BigDecimal(1 + rand.nextInt(20_000));}private String account() {return 'test-account ' + rand.nextInt(1000) + 1000;}private String address() {return 'Test Street ' + rand.nextInt(100) + 1;}private String iban() {return 'test-iban-' + rand.nextInt(1000) + 1000;}}

這只是一個簡單的模擬功能,可讓我們看到系統的運行情況。 在現實世界中,我們不會使用任何生成器,而可能會使用某些公開的服務。 現在,在resources文件夾下創建一個新的spring配置文件– invoices-context.xml并聲明組件掃描和任務計劃支持:

<?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:task = 'http://www.springframework.org/schema/task'xmlns:context = 'http://www.springframework.org/schema/context'xsi:schemaLocation = 'http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd'><import resource = 'invoices-int-schema.xml' /><context:component-scan base-package = 'com.vrtoonjava.invoices' /><context:component-scan base-package = 'com.vrtoonjava.banking' /><task:executor id = 'executor' pool-size='10' /><task:scheduler id = 'scheduler' pool-size='10' /><task:annotation-driven executor='executor' scheduler='scheduler' /></beans>

要查看整個運行過程,我們還需要最后一塊-標準Java主應用程序,我們將在其中創建Spring的ApplicationContext。

package com.vrtoonjava.invoices;import org.springframework.context.support.ClassPathXmlApplicationContext;/*** Entry point of the application.* Creates Spring context, lets Spring to schedule job and use schema.*/ public class InvoicesApplication {public static void main(String[] args) {new ClassPathXmlApplicationContext('/invoices-context.xml');}}

只需從命令行運行mvn clean install并在InvoicesApplication類中啟動main方法。 您應該能夠看到類似的輸出:

===========> Sending 10 invoices to the system Amount of $3441 can be automatically processed by system Amount of $17419 can not be automatically processed by system Processing payment Payment{senderAccount=current-local-acc, receiverAccount=test-account 1011000, dollars=3441} Amount of $18442 can not be automatically processed by system Amount of $19572 can not be automatically processed by system Amount of $5471 can be automatically processed by system Amount of $1663 can be automatically processed by system Processing payment Payment{senderAccount=current-iban-acc, receiverAccount=test-iban-2211000, dollars=5471} Amount of $13160 can not be automatically processed by system Amount of $2213 can be automatically processed by system Amount of $1423 can be automatically processed by system Processing payment Payment{senderAccount=current-iban-acc, receiverAccount=test-iban-8051000, dollars=1663} Amount of $1267 can be automatically processed by system Payment failed: org.springframework.integration.MessageHandlingException: com.vrtoonjava.banking.PaymentException: Banking services are offline, try again later! Processing payment Payment{senderAccount=current-iban-acc, receiverAccount=test-iban-6141000, dollars=1423} Processing payment Payment{senderAccount=current-local-acc, receiverAccount=test-account 6761000, dollars=1267}

參考: Spring Integration –從頭開始的應用程序,來自我們的JCG合作伙伴 Michal Vrtiak的第2部分 ,在vrtoonjava博客上。

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

總結

以上是生活随笔為你收集整理的Spring集成–从头开始应用程序,第2部分的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。