Java 如何使用Spring连接多个侦听器样式bean
在春天,我真的找不到一个简洁的方法来做到这一点——想象一下,我有一个可以监听消息的类:Java 如何使用Spring连接多个侦听器样式bean,java,spring,dependency-injection,Java,Spring,Dependency Injection,在春天,我真的找不到一个简洁的方法来做到这一点——想象一下,我有一个可以监听消息的类: @Component public class MessageReceiver { private List<MessageHandler> handlers = new ArrayList<>(); public void receiveMessage(Message m) { for(MessageHandler handler: handlers) {
@Component
public class MessageReceiver {
private List<MessageHandler> handlers = new ArrayList<>();
public void receiveMessage(Message m) {
for(MessageHandler handler: handlers) {
handler.process(m);
}
}
public void registerMessageHandler(MessageHandler handler) {
handlers.add(handler);
}
}
@组件
公共类消息接收器{
私有列表处理程序=新的ArrayList();
公共无效接收消息(消息m){
for(MessageHandler:handlers){
处理程序(m);
}
}
公共无效注册表MessageHandler(MessageHandler){
添加(handler);
}
}
基本上,我希望能够定义多个MessageHandler
bean,并让它们自己自动注册到MessageReceiver
。我不想在某个地方维护一个MessageHandler
的列表——我只想让Spring在上下文中找到任何一个(可能是带注释的@Bean
或@Component
),并让他们调用registerMessageHandler()
方法作为连接过程的一部分
最整洁的方法是什么?您是否考虑过使用Spring中已经包含的事件发布机制
ApplicationEventPublisher
可以是@自动连线的
,如果您使用Spring 4.2或更新版本,Spring将连接实现ApplicationListener
或带有@EventListener
注释的方法的任何@组件
各种Spring组件(如Spring security)都使用此功能来广播事件,例如当用户进行身份验证时
你可以看看这个
编辑
如果您不喜欢使用内置消息机制,您可以使用相同的自动检测原理构建自己的消息机制
Spring的当前版本允许您基于类型@AutoWire
一个bean列表,如果所有MessageHandler
实例都是bean,那么它将如下所示
@Component
public class MessageReceiver {
private final List<MessageHandler> handlers;
@Autowired
public MessageReceiver(List<MessageHandler> handlers) {
this.handlers = handlers;
}
public void receiveMessage(Message m) {
for (MessageHandler handler : handlers) {
handler.process(m);
}
}
}
@组件
公共类消息接收器{
私人最终名单处理人;
@自动连线
public MessageReceiver(列表处理程序){
this.handlers=handlers;
}
公共无效接收消息(消息m){
for(MessageHandler:handlers){
处理程序(m);
}
}
}
如果您使用的Spring版本不支持自动关联集合,那么您应该实现
ApplicationContextAware
来获取对ApplicationContext的引用,这样您就可以调用getBeansOfType()
来获取所有的MessageHandler。我想它可以正常工作,但这有点像黑客攻击,滥用事件机制来做它不该做的事情。我想我更喜欢在@Configuration
bean中维护一个处理程序列表,如果需要做一些额外的工作,这至少是正确的。如果您的处理程序是事先知道的(听起来像),那么它们应该是单例bean,这意味着您可以从Spring上下文中获取它们。通过使用ApplicationContextAware
MessageReceiver
并使用getBeansOfType
进行查找,或者通过@Autowiring
将列表
插入MessageReceiver
。如果处理程序是短暂的,那么您可能需要在代码中注册/取消注册它们。啊,我还没有看到自动连接的集合-这似乎正是我想要的。