簡體   English   中英

在Java Spring Integration中,轉換器元素可以包括路由器功能嗎?

[英]In Java Spring Integration, can a transformer element include router functionality?

我需要一個組件:

  1. 接收一條消息,對消息的有效負載和標頭進行轉換(到目前為止,它的作用就像一個轉換器)。

  2. 然后,基於在標頭路由上傳遞到適當通道的值(充當標頭路由器)。

我只想使用Java中的注釋而不是XML來配置它,但是我絕對會考慮到這一點。 如果有人知道XML解決方案,請傳遞它。

如果有幫助,我的用例是我希望轉換器對消息有效負載執行的轉換依賴於自定義加載的標頭值。 我還希望用於從變壓器發送消息的通道取決於標頭值。

我知道該解決方案涉及多個轉換器,每個轉換類型(在標頭值中定義)一個,然后一個路由器。 我試圖避免這種解決方案,並且最多只能使用一個路由器和一個變壓器。

謝謝您的幫助。

在Spring Integration中,渠道就像其他任何bean一樣。 您可以使用服務激活器在任何bean上調用方法。 該bean可以注入所需的通道。 您可以使用@Qualifier批注來選擇應該注入哪個通道,或者只是自動將Map<String, MessageChannel>夾在其中,然后通過該通道的Bean名稱進行索引。 它可以將轉換后的消息傳遞到那些通道。

Spring Boot應用程序:

package demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
import org.springframework.integration.config.EnableIntegration;

@SpringBootApplication
@EnableIntegration
@ImportResource("classpath:int.xml")
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }


}

網關接口:

package demo;

public interface MyGateway {
    public void send(Object o);
}

要調用的服務:

package demo;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    private final Map<String, MessageChannel> channels;

    @Autowired
    public MyService(Map<String, MessageChannel> channels) {
        super();
        this.channels = channels;
    }

    public void transformAndRoute(Message<?> in) {
        // do your business logic here
        Message<?> out = MessageBuilder.fromMessage(in).build();

        // if(something)...
        channels.get("fooChannel").send(out);
    }

}

集成配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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">

    <int:gateway id="myGateway" service-interface="demo.MyGateway"
        default-request-channel="inChannel" />

    <int:service-activator input-channel="inChannel"
        ref="myService" method="transformAndRoute" />

    <int:channel id="inChannel" />


    <int:logging-channel-adapter id="fooChannel" level="INFO" log-full-message="true"/>

</beans>

最后是一個簡單的集成測試:

package demo;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=DemoApplication.class)
public class MyGatewayIT {

    @Autowired
    MyGateway myGateway;

    @Test
    public void test() {
        myGateway.send(new Object());

        // do your assertions here
    }

}

輸出:

14:17:19.733 [main] DEBUG o.s.i.handler.LoggingHandler - org.springframework.integration.handler.LoggingHandler#0 received message: GenericMessage [payload=java.lang.Object@6f2cfcc2, headers={id=6791344c-07b4-d420-0d17-e2344f4bf15b, timestamp=1437826639733}]

開發基於消息的系統的主要好處是,您可以使用易於測試,重用和更改的小型,松散耦合的組件創建應用程序。 創建在流程中扮演兩個角色的組件會破壞該規則。 另外,如果您按上述方式創建代碼,則您的代碼確實與Spring Integration相關聯。 相反,您可以做的是創建幾個組件,每個組件都有一個職責,然后將它們配置為以鏈狀運行。

您可以做的是創建一個修改消息的有效負載和標頭的轉換器。 該轉換器將封裝您的業務邏輯,並設置一個標頭(例如myRoutingHeader ),該標頭稍后可用於路由。 最好有一個用於業務邏輯的轉換器,以及一個用於添加標頭的標頭濃縮器。 但是,讓我們假設您是在一個單獨的類中進行操作。 將該類定義為bean(例如myTransformer )。 然后在您的配置中:

<int:channel id="inChannel/>

<!-- if performance is important consider using a SpEL expression to 
    invoke your method instead as they can be configured to be compiled -->
<int:transformer ref="myTransformer" input-channel="inChannel"
             method="transform" output-channel="routingChannel"/>

<int:channel id="routingChannel/>

<int:header-value-router input-channel="routingChannel" header-name="myRoutingHeader">
    <int:mapping value="foo" channel="fooChannel" />
    <int:mapping value="bar" channel="barChannel" />
</int:header-value-router>

聽起來像鏈條會幫你

<chain input-chanel="source" output-channel="routing-channel">
 <transform/>
 <!-- any enrichment process or intermediate process can go here -->
</chain>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM