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數據了,然後就可以愉快的進行代碼編寫了

努力成就非凡,請不要在最該奮鬥的年紀選擇安逸

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