在一些業務場景中,當容器初始化完成以後,須要處理一些操做,好比一些數據的加載、初始化緩存、特定任務的註冊等等。這個時候咱們就可使用Spring提供的ApplicationListener來進行操做。java
本文以在Spring boot下的使用爲例來進行說明。首先,須要實現ApplicationListener接口並實現onApplicationEvent方法。把須要處理的操做放在onApplicationEvent中進行處理:spring
package com.secbro.learn.context; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; public class ApplicationStartListener implements ApplicationListener<ContextRefreshedEvent>{ @Override public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { System.out.println("個人父容器爲:" + contextRefreshedEvent.getApplicationContext().getParent()); System.out.println("初始化時我被調用了。"); } }
而後,實例化ApplicationStartListener這個類,在Spring boot中經過一個配置類來進行實例化:緩存
package com.secbro.learn.conf; import com.secbro.learn.context.ApplicationStartListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ListenerConfig { @Bean public ApplicationStartListener applicationStartListener(){ return new ApplicationStartListener(); } }
隨後,啓動Spring boot服務,打印出一下內容:bash
個人父容器爲:null 初始化時我被調用了。
從打印的結果能夠看出,ApplicationStartListener的onApplicationEvent方法在容器啓動時已經被成功調用了。而此時初始化的容器爲root容器。app
此處使用Spring boot來進行操做,沒有出現二次調用的問題。在使用傳統的application.xml和project-servlet.xml配置中會出現二次調用的問題。主要緣由是初始化root容器以後,會初始化project-servlet.xml對應的子容器。咱們須要的是隻執行一遍便可。那麼上面打印父容器的代碼用來進行判斷排除子容器便可。在業務處理以前添加以下判斷:ide
if(contextRefreshedEvent.getApplicationContext().getParent() != null){ return; }if(contextRefreshedEvent.getApplicationContext().getParent() != null){ return; }
這樣其餘容器的初始化就會直接返回,而父容器(Parent爲null的容器)啓動時將會執行相應的業務操做。spa
在spring中InitializingBean接口也提供了相似的功能,只不過它進行操做的時機是在全部bean都被實例化以後才進行調用。根據不一樣的業務場景和需求,可選擇不一樣的方案來實現。code