代码之家  ›  专栏  ›  技术社区  ›  ykaganovich Mike Samuel

如何处理spring事件图?

  •  0
  • ykaganovich Mike Samuel  · 技术社区  · 5 年前

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

    Y-监听ConfigMsg,读取B,构建YB

    我怎样才能告诉Z XA和YB都是可用的,因为它们会被X和Y独立地激发呢?

    0 回复  |  直到 5 年前
        1
  •  1
  •   Mark Bramnik    5 年前

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

    将应用程序事件通知为此应用程序注册的所有匹配侦听器。事件可以是框架事件(如ContextRefreshedEvent)或特定于应用程序的事件。 这样的事件发布步骤实际上是向多主机的转移,并不意味着同步/异步执行,甚至根本不意味着立即执行。鼓励事件监听器尽可能高效,单独使用异步执行来执行更长时间的运行和可能阻塞的操作。

    所以基本上你可以:

    1. 创建3种不同类型的事件:“ConfigMsgAvailable”、“XaisBuild”、“YbisBuild”,
    2. Z将监听“xaisbuild”和“ybisbuild”事件,并将产品存储在内部(在其内部状态下),状态刷新只会在XA和YB都可用时发生(我不知道“状态刷新”到底是什么,但假设它来自您的域,通常超出了问题的范围)

    所以你会得到这样的结果:

    @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()); 
        }
    }