我正在使用 Spring Integration 并尝试处理
TcpConnectionOpenEvent
和 TcpConnectionCloseEvent
来收集连接上的指标并写入日志。但是,我无法正确收听这些事件。
这是在没有拦截器的情况下工作的
但是当我添加如下所示的拦截器工厂链时,事件侦听器不起作用。
您能否提供有关如何为这些连接事件正确设置事件侦听器的指导?
以下是我的相关配置:
<int-ip:tcp-connection-factory id="crLfServer"
using-nio="false"
deserializer="serverDeserializer"
serializer="serverSerializer"
single-use="false"
lookup-host="false"
type="server"
**interceptor-factory-chain="serverConnectionInterceptorFactoryChain"**
task-executor="incomingTaskExecutor"
ssl-context-support="${sslcontext.server.beanname}"
socket-support="requireClientAuthSocketSupport"
port="${local.server.port}"/>
<int-ip:tcp-inbound-gateway id="gatewayCrLf"
reply-timeout="${pos.server.timeout}"
connection-factory="crLfServer"
request-channel="serverInChannelPos"
reply-channel="serverOutChannelPos"
error-channel="errorChannel" />
<int:channel id="serverOutChannelPos">
<int:interceptors>
<ref bean="serverOutInterceptor"/>
<ref bean="errorMessageChannelInterceptor"/>
</int:interceptors>
</int:channel>
<int:channel id="serverInChannelPos">
<int:interceptors>
<ref bean="serverInInterceptor"/>
</int:interceptors>
</int:channel>
我还添加了一个事件监听器类:
@Component
@Slf4j
public class TcpConnectionEventListener {
@EventListener
public void handleTcpConnectionOpen(TcpConnectionOpenEvent event) {
log.info("TCP connection opened: {}", event.getConnectionId());
//collect metrics
//some other actions...
}
@EventListener
public void handleTcpConnectionClose(TcpConnectionCloseEvent event) {
log.info("TCP connection closed: {}", event.getConnectionId());
//collect metrics
//some other actions...
}
}
@Bean
@Lazy
public TcpConnectionInterceptorFactoryChain serverConnectionInterceptorFactoryChain(){
TcpConnectionInterceptorFactoryChain tcpConnectionInterceptorFactoryChain = new TcpConnectionInterceptorFactoryChain();
TcpConnectionInterceptorFactory[] tcpConnectionInterceptorFactories = {
serverRetailerNumberValidationInterceptorFactory(),
serverStoringConnectionIdInterceptorFactory()};
tcpConnectionInterceptorFactoryChain.setInterceptors(tcpConnectionInterceptorFactories);
return tcpConnectionInterceptorFactoryChain;
}
问题是我没有看到 @EventListener 方法的任何日志,而且它们似乎根本没有被触发。您能帮我确定可能出了什么问题以及如何让这些事件与拦截器一起正常工作吗?
所以,经过一些本地测试,这里是一个结论。
当您使用
TcpConnectionInterceptorFactoryChain
时,您必须确保 TcpConnectionInterceptorFactory
生成由 TcpConnectionInterceptorSupport
提供的 ApplicationEventPublisher
。例如这样:
public class HelloWorldInterceptorFactory implements
TcpConnectionInterceptorFactory, ApplicationEventPublisherAware {
private volatile ApplicationEventPublisher applicationEventPublisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
@Override
public TcpConnectionInterceptorSupport getInterceptor() {
return new HelloWorldInterceptor(this.hello, this.world, this.applicationEventPublisher);
}
}
ConnectionFactory
会自动提供一个,但它不负责改变上述工厂提供的拦截器实例。因此,如果我们想发出上述事件,则目标项目有责任正确连接拦截器。