spring事件广播机制

https://blog.csdn.net/liereli/article/details/79928024

打个比方,当我们和其他公司进行业务接口对接时,我们这边需要保存或者修改某些数据,但是保存和修改这些数据对整个流程没有太大的影响,这个时候我们应该怎么做呢?是的,我们要考虑异步去保存或者修改数据,但怎么去异步保存数据呢?这个时候我们就可以使用事件广播来做这个操作

看过spring源码的大神都知道,当我们初始化容器的过程中,我们会有initApplicationEventMulticaster()--->在此方法在org.springframework.context.support.AbstractApplicationContext.refresh()中-->在此方法org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh()中-->在此方法org.springframework.boot.SpringApplication.refresh(ApplicationContext applicationContext)-->refreshContext(ConfigurableApplicationContext context)-->run(String... args),默认情况使用的事件广播是SimpleApplicationEventMulticaster这个类,这个类中有Executor接口,感觉是不是很熟悉?提示一下,线程池。如果还不熟悉的请自行百度,我们需要手动去设置这个线程池,该怎么配置呢?请看

<!--异步事件处理
    在AbstractApplicationContext 初始化应用事件传播时,会从beanFactory中获取是否存在广播器,
    如果不存在则用SimpleApplicationEventMulticaster
    如果想自定义此广播器,则id='applicationEventMulticaster'-->
<bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster">
    <property name="taskExecutor" ref="coreTaskExecutor"/>
</bean>

<bean id="coreTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="10"/>
    <property name="maxPoolSize" value="20"/>
    <property name="queueCapacity" value="25"/>
    <property name="threadNamePrefix" value="coreTaskExecutor"/>
</bean>
在applicationContext.xml中配置,如果使用的springboot,可以使用

@ImportResource("classpath:applicationContext.xml")

来导入xml文件

配置好了之后,我们可以定义我们自己的事件和监听器了

创建事件类,需要继承ApplicationEvent

public class TestEvent extends ApplicationEvent {

   public TestEvent(Object source) {
      super(source);
   }
}
Object对象就是我们需要传递的参数

接着,定义我们的监听,需要实现ApplicationListener这个接口

public class TestListener implements ApplicationListener {
   @Override
   public void onApplicationEvent(ApplicationEvent event) {
      if(!(event instanceof TestEvent)){
         return;
      }
      event.getSource();//获取传递的参数,即:和TestEvent中的source一样的
      //再次处理业务逻辑    TODO    
   }
}
我们主要是在监听器中处理业务逻辑

是不是想到了个问题,参数怎么传递过来的呢?别着急,我们慢慢来

参数当然是从我们正常处理业务逻辑代码中传递过来的了,监听器中的代码只是处理分支的情况,正常情况,我们一般都是在service的实现类中进行事件广播并传递参数,此类必须实现ApplicationContextAware这个接口

public class TestServiceImpl implements ApplicationContextAware{
   ApplicationContext applicationContext;

   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
      this.applicationContext = applicationContext;
   }

   public void test(){
      String datas = "";//传递参数也可以是map、list、实体对象等
       applicationContext.publishEvent(new TestEvent(datas));
   }
}
那么在监听器中就可以接收到datas数据了,然后就可以愉快的进行代码编写了

努力成就非凡,请不要在最该奋斗的年纪选择安逸

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章