如何使用Spring Integration动态创建多个TcpOutboundGateways?

时间:2019-06-14 16:55:45

标签: java spring spring-boot tcp spring-integration

我有一个场景,我需要一个客户端应用程序,以便能够在应用程序启动时动态创建与可变数量的唯一主机/端口组合的TCP连接。我正在尝试使用Spring Integration TcpOutboundGateway完成此任务,但一直找不到解决方案。我希望每个主机/端口组合都具有自己专用的TcpOutboundGateway。到目前为止,我对TcpOutboundGateway的研究使我想到了以下单个网关解决方案……

@MessageGateway(defaultRequestChannel=“sendMessage”)
public interface myMessageGateway {
    byte[] sendMessage(String message);
}

@Bean
@ServiceActivator(inputChannel=“sendMessage”)
public MessageHandler tcpOutboundGateway(AbstractClientConnectionFactory factory) {
    TcpOutboundGateway gateway = new TcpOutboundGateway();
    gateway.setConnectionFactory(factory);
    return gateway;
}

@Bean
public AbstractClientConnectionFactory clientConnectionFactory() {
    return new TcpNetClientConnectionFactory(“123.456.789.0”, 5555);
}

据我所知,调用sendMessage函数会将请求消息放在“ sendMessage”通道上。然后,该通道会将其传递给tcpOutboundGateway服务激活器,该服务激活器将处理消息的发送并最终返回服务器的响应作为sendMessage函数的返回。在单个预定义服务器连接的情况下,该解决方案对我来说效果很好。

我的问题是如何以一种可以支持一组可变的唯一主机/端口的方式动态创建新的消息网关和服务激活器?更具体地说,@ MessageGateway和@ServiceActivator批注在后台为我们做什么?为了复制该功能,我需要做什么?

编辑:

因此,在进行了一些实验之后,我找到了这个解决方案,似乎可以解决问题……

// Define the Message Gateway without any annotations
public interface MyMessageGateway {
    byte[] sendMessage(String message);
}

...

// Use the GatewayProxyFactoryBean to replicate the functionality of the @MessageGateway annotation
// context is my instance of a ConfigurableApplicationContext
GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean(SenderGateway.class);
gpfb.setDefaultRequestChannel(“sendMessage”);
context.getBeanFactory().registerSingleton(“MyMessageGateway”, gpfb);
context.getBeanFactory().initializeBean(gpfb, “MyMessageGateway”);

// Create and register the ClientConnectionFactory Bean within the Application Context
AbstractClientConnectionFactory clientConnectionFactory = new TcpNetClientConnectionFactory(“123.456.789.0”, 5000);
context.getBeanFactory().registerSingleton(“ClientConnectionFactory”, clientConnectionFactory);
context.getBeanFactory().initializeBean(clientConnectionFactory, “ClientConnectionFactory”);

// Create and register the TcpOutboundGateway Bean within the Application Context
TcpOutboundGateway gateway = new TcpOutboundGateway();
gateway.setConnectionFactory(clientConnectionFactory);
context.getBeanFactory().registerSingleton(“TcpOutboundGateway”, tcpOutboundGateway);
context.getBeanFactory().initializeBean(tcpOutboundGateway, “TcpOutboundGateway”);

// Create and register the Request Channel to connect the Message Gateway and the TCP Outbound Gateway
// This should replicate the functionality of the @ServiceActivator annotation
DirectChannel sendMessage = new DirectChannel();
sendMessage.setBeanName(“sendMessage”);
context.getBeanFactory().registerSingleton(“sendMessage”, sendMessage);
context.getBeanFactory().initializeBean(sendMessage, “sendMessage”);

// Subscribe the TCP Outbound Gateway to the new Message Channel (sendMessage)
// This should replicate the functionality of the @ServiceActivator annotation
sendMessage.subscribe(tcpOutboundGateway);

// Start the ClientConnectionFactory
// This seems to be getting done automatically in the non-dynamic implementation above
clientConnectionFactory.start();

此实现允许以与上述带注释的实现相同的方式(使用为MyMessageGateway接口定义的sendMessage函数)通过​​消息网关和TCP出站网关发送消息。我发现为了将这种方法用于一种以上的主机/端口组合,您将需要通过context.getBeanFactory.getBean()获得所需的消息网关。

我很好奇这种方法/实施中是否存在缺陷?

1 个答案:

答案 0 :(得分:1)

唯一的简单方法是考虑将动态PrimeFaces.current().ajax().update("userDialog:yourFormId"); 与Spring Integration提供的Java DSL配合使用:https://docs.spring.io/spring-integration/docs/current/reference/html/#java-dsl-runtime-flows

我们还为类似的动态TCP客户端用例提供了一个完整的示例:https://github.com/spring-projects/spring-integration-samples/tree/master/advanced/dynamic-tcp-client