如何处理spring事件图?

vltsax25  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(276)

我有一个spring应用程序,它可以接收一个大的配置消息。我们使用applicationeventpublisher来发布事件,@eventlistener注解来订阅它们。
不同的组件对消息的不同部分感兴趣,并基于它创建各种对象。假设configmsg有属性a和b。
x-监听configmsg,读取a,构建xa
y-监听configmsg,读取b,构建yb
z-想要得到xa和yb,然后刷新它的状态。
我怎样才能告诉z xa和yb都是可用的,因为它们会被x和y独立地激发呢?

aelbi1ox

aelbi1ox1#

简而言之,spring事件监听器不提供任何高级功能,当您发送消息时,它会通知所有监听器,仅此而已。从文档中
将应用程序事件通知为此应用程序注册的所有匹配侦听器。事件可以是框架事件(如contextrefreshedevent)或特定于应用程序的事件。这样的事件发布步骤实际上是向多主机的转移,并不意味着同步/异步执行,甚至根本不意味着立即执行。鼓励事件监听器尽可能高效,单独使用异步执行来执行更长时间的运行和可能阻塞的操作。
所以基本上你可以:
创建3种不同类型的事件:“configmsgavailable”、“XaisBuild”、“YbisBuild”,
x和y都将监听“configmsgavailable”类型的事件,一旦收到,将分别构建xa和yb
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()); 
    }
}

相关问题