Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用Spring连接多个侦听器样式bean_Java_Spring_Dependency Injection - Fatal编程技术网

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
。如果处理程序是短暂的,那么您可能需要在代码中注册/取消注册它们。啊,我还没有看到自动连接的集合-这似乎正是我想要的。