【问题标题】:How to deal with spring event graph?如何处理spring事件图?
【发布时间】:2021-01-26 04:01:48
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: java spring events


    【解决方案1】:

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

    通知所有在此应用程序中注册的匹配侦听器应用程序事件。事件可以是框架事件(例如 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()); 
        }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      • 1970-01-01
      • 2013-08-26
      相关资源
      最近更新 更多