Spring SpringMVC在啟動完成后執(zhí)行方法源碼解析
關鍵字:spring容器加載完畢做一件事情(利用ContextRefreshedEvent事件)
應用場景:很多時候我們想要在某個類加載完畢時干某件事情,但是使用了spring管理對象,我們這個類引用了其他類(可能是更復雜的關聯(lián)),所以當我們?nèi)ナ褂眠@個類做事情時發(fā)現(xiàn)包空指針錯誤,這是因為我們這個類有可能已經(jīng)初始化完成,但是引用的其他類不一定初始化完成,所以發(fā)生了空指針錯誤,解決方案如下:
1、寫一個類繼承spring的ApplicationListener監(jiān)聽,并監(jiān)控ContextRefreshedEvent事件(容易初始化完成事件)
2、定義簡單的bean:<bean id="beanDefineConfigue"
class="com.creatar.portal.webservice.BeanDefineConfigue"></bean>或者直接使用@Component("BeanDefineConfigue")注解方式
完整的類如下:
package com.creatar.portal.webservice; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; @Component("BeanDefineConfigue") public class BeanDefineConfigue implements ApplicationListener<ContextRefreshedEvent> {//ContextRefreshedEvent為初始化完畢事件,spring還有很多事件可以利用 // @Autowired // private IRoleDao roleDao; /** * 當一個ApplicationContext被初始化或刷新觸發(fā) */ @Override public void onApplicationEvent(ContextRefreshedEvent event) { // roleDao.getUserList();//spring容器初始化完畢加載用戶列表到內(nèi)存 System.out.println("spring容易初始化完畢================================================"); } }
或者使用xml配置方式(非注解),簡單配置個bean即可
<bean id="beanDefineConfigue" class="com.creatar.portal.webservice.BeanDefineConfigue"></bean>
其他定義方式,完整的類如下:
package com.creatar.portal.webservice; import java.util.ArrayList; import java.util.List; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; @Component("BeanDefineConfigue2") public class BeanDefineConfigue2 implements ApplicationListener<ApplicationEvent> { List<String> list = new ArrayList<String>(); /** * 當一個ApplicationContext被初始化或刷新觸發(fā) */ @Override public void onApplicationEvent(ApplicationEvent event) { if (event instanceof ContextRefreshedEvent) { System.out.println("spring容易初始化完畢================================================888"); } } }
spring其他事件:
spring中已經(jīng)內(nèi)置的幾種事件:
ContextClosedEvent 、ContextRefreshedEvent 、ContextStartedEvent 、ContextStoppedEvent 、RequestHandleEvent
后續(xù)研究:
applicationontext和使用MVC之后的webApplicationontext會兩次調(diào)用上面的方法,如何區(qū)分這個兩種容器呢?
但是這個時候,會存在一個問題,在web 項目中(spring mvc),系統(tǒng)會存在兩個容器,一個是root application context ,另一個就是我們自己的 projectName-servlet context(作為root application context的子容器)。
這種情況下,就會造成onApplicationEvent方法被執(zhí)行兩次。為了避免上面提到的問題,我們可以只在root application context初始化完成后調(diào)用邏輯代碼,其他的容器的初始化完成,則不做任何處理,修改后代碼如下:
@Override public void onApplicationEvent(ContextRefreshedEvent event) { if(event.getApplicationContext().getParent() == null){//root application context 沒有parent,他就是老大. //需要執(zhí)行的邏輯代碼,當spring容器初始化完成后就會執(zhí)行該方法。 } }
后續(xù)發(fā)現(xiàn)加上以上判斷還是能執(zhí)行兩次,不加的話三次,最終研究結(jié)果使用以下判斷更加準確:event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext")
總結(jié)
以上就是本文關于SpringMVC在啟動完成后執(zhí)行方法源碼解析的全部內(nèi)容,希望對大家有所幫助。有什么問題,可以留言,小編會及時回復大家的。在此也非常感謝大家對本站的支持!
相關文章
Mybatis RowBounds 限制查詢條數(shù)的實現(xiàn)代碼
Oracle 數(shù)據(jù)庫查詢增加RowBounds限制查詢條數(shù),默認是0到1000條。下面給大家分享Mybatis RowBounds 限制查詢條數(shù)的實現(xiàn)代碼,需要的朋友參考下吧2016-11-11SpringBoot整合Spring?Boot?Admin實現(xiàn)服務監(jiān)控的方法
這篇文章主要介紹了SpringBoot整合Spring?Boot?Admin實現(xiàn)服務監(jiān)控,內(nèi)容包括Server端服務開發(fā),Client端服務開發(fā)其中Spring Boot Admin還可以對其監(jiān)控的服務提供告警功能,如服務宕機時,可以及時以郵件方式通知運維人員,感興趣的朋友跟隨小編一起看看吧2022-03-03Java?CopyOnWriteArrayList源碼超詳細分析
為了將讀取的性能發(fā)揮到極致,jdk中提供了CopyOnWriteArrayList類,下面這篇文章主要給大家介紹了關于java中CopyOnWriteArrayList源碼解析的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-11-11