首页 > 解决方案 > 如何处理spring事件图?

问题描述

我有一个可以接收大配置消息的 Spring 应用程序。我们使用 ApplicationEventPublisher 来发布事件,并使用 @EventListener 注解来订阅它们。

不同的组件对消息的不同部分感兴趣,并基于它创建各种对象。假设 ConfigMsg 具有属性 A 和 B。

X - 监听 Co​​nfigMsg,读取 A,构建 XA

Y - 监听 Co​​nfigMsg,读取 B,构建 YB

Z - 想要获得 XA 和 YB 然后刷新它的状态。

我如何通知 Z XA 和 YB 都可用,因为它们会被 X 和 Y 独立解雇?

标签: javaspringevents

解决方案


简而言之,spring 事件侦听器不提供任何高级功能,当您发送消息时,它会通知所有侦听器,仅此而已。从文档

通知在此应用程序中注册的所有匹配侦听器应用程序事件。事件可以是框架事件(例如 ContextRefreshedEvent)或特定于应用程序的事件。这样的事件发布步骤实际上是对多播器的切换,并且根本不暗示同步/异步执行甚至立即执行。鼓励事件侦听器尽可能高效,单独使用异步执行来进行更长时间运行和可能阻塞的操作。

所以基本上你可以:

  1. 创建 3 种不同类型的事件:“ConfigMsgAvailable”、“XAIsBuilt”、“YBIsBuilt”、
  2. X 和 Y 都将监听“ConfigMsgAvailable”类型的事件,一旦收到将分别构建 XA 和 YB
  3. Z 将同时监听“XAIsBuilt”和“YBIsBuilt”事件,并将产品存储在内部(在其内部状态),状态刷新只会在 XA 和 YB 可用时发生(我不知道“状态刷新”是什么) ' 是完全正确的,但假设它来自您的域并且通常超出了问题的范围)

所以你会为 Z 得到这样的东西:

@Component // a singleton bean in spring
public class Z {
    private XA xa; // = null initially
    private YB yb; // = null initially
    ... internal state ...
    public Z() {
       // don't initialize anything    
    }   

    public void receiveXAAndTryRefreshState(XA xa) {
      this.xa = xa;
      tryRefreshState();
    } 

    public void receiveYBAndTryRefreshState(YB yb) {
      this.yb = yb;
      tryRefreshState();
    } 

    private void tryRefreshState() {
      if(this.xa != null && this.yb != null) {
        doActualRefresh();
      }
    }
}

然后放置 2 个事件侦听器,实际的 Spring 明智实现可能因 Spring 版本而异,这是一种选择:


@Component
public class XAIsBuiltEventListener implements ApplicationListener<XAIsBuilt> {
    @Autowired
    private Z z;
    @Override
    public void onApplicationEvent(AXIsBuilt event) {
        z.receiveXAAndTryRefreshState(event.getXA()); 
    }
}

@Component
public class YBIsBuiltEventListener implements ApplicationListener<YBIsBuilt> {
    @Autowired
    private Z z;
    @Override
    public void onApplicationEvent(YBIsBuilt event) {
        z.receiveYBAndTryRefreshState(event.getYB()); 
    }
}


推荐阅读