在我的应用程序中,我按如下方式配置了一些通道:
@Bean
public MessageChannel eventFilterChannel() {
return new ExecutorChannel(asyncConfiguration.getAsyncExecutor());
}
@Bean
public MessageChannel processEventChannel() {
return new ExecutorChannel(asyncConfiguration.getAsyncExecutor());
}
我正在使用ExecutorChannel
并使用我的自定义Executor
,如下所示:
@Configuration
@EnableAsync
public class AsyncConfiguration extends AsyncConfigurerSupport {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(100);
executor.setMaxPoolSize(100);
executor.setQueueCapacity(1000);
executor.setThreadNamePrefix("MyAppThread");
executor.initialize();
return executor;
}
}
我有以下MessageEndpoint
,它是eventFilterChannel
频道的订阅者:
@MessageEndpoint
public class MyEventFilter {
@Filter(inputChannel = "eventFilterChannel", outputChannel = "processEventChannel")
public boolean filterEvents(final MyEvent myEvent) {
//filter logic
}
}
理想情况下,我希望我的事件过滤器消息端点是多线程的,因为我正在使用ExecutorChannel
。我想了解这是否是多线程端点的正确实现?
但是,我很怀疑,因为我可以在日志中看到以下内容:
Channel 'application.eventFilterChannel' has 1 subscriber(s).
我的实施是否正确或是否有我可以遵循的标准?
答案 0 :(得分:1)
嗯,有一点误导。您的eventFilterChannel
实际上只有一个订阅者 - 您的@Filter
。但它确实是多线程的。在几个线程中使用相同的无状态组件。
ExecutorChannel
对传入任务进行排队,并且它们在池中的线程上并行执行。在我们的例子中,故事是关于消息传递。不确定代码是否可以帮助您,但它看起来像:
public final boolean dispatch(final Message<?> message) {
if (this.executor != null) {
Runnable task = createMessageHandlingTask(message);
this.executor.execute(task);
return true;
}
return this.doDispatch(message);
}
Runnable
的含义如下:
public void run() {
doDispatch(message);
}
...
handler.handleMessage(message);
此handler
只是@Filter
的订阅者。
因此,从不同的线程调用相同的方法。由于这是被动和无状态组件,因此只保留一次并从不同线程重用是安全的。
另一方面,超出主题:如果您向此频道添加更多订阅者,则无论如何都不会并行调用它们:默认情况下,它是循环策略:根据下一个消息选择处理程序指数。
如果一个处理程序无法处理消息,我们尝试下一个,依此类推。您可以注入任何其他自定义实现。或者甚至将其重置为null
以始终从第一个开始。