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數據了,然後就可以愉快的進行代碼編寫了
努力成就非凡,請不要在最該奮鬥的年紀選擇安逸