父子容器

特殊說明:

ContextLoaderListener: 創建的容器爲父容器(applicationContext.xml)

DispatcherServlet:創建的容器爲子容器(appServlet-context.xml)

1、問題:同一個類可以被子容器和父容器同時生成實例嗎?

答案:可以,並且是不同的實例

2、問題:如果一個類子容器(appServlet-context.xml)有實例,父容器(applicationContext.xml)也有實例,getBean 使用的是那個?

答案:

1、從父容器取:是父容器的實例,

2、從子容器取值:優先使用子容器的實例;子容器沒有嘗試去父容器取

3、問題:子容器(DispatcherServlet)支持 AOP嗎?

答案:支持

注意:

1、要確保對應容器的配置文件(appServlet-context.xml/applicationContext.xml)擁有<aop:aspectj-autoproxy/> 等與AOP相關的配置

2、子容器配置的AOP 植入邏輯,對父容器無效;即配置僅對當前容器的實例有效;

本質上是因爲創建實例時,因爲當前容器有實現BeanPostProcessor接口的AnnotationAwareAspectJAutoProxyCreator 實例,創建bean對象時,生成了AOP代理,才具備AOP功能的。

4、問題:子容器是否支持事務?

答案:支持,同AOP,appServlet-context.xml文件必須有對應的配置

注意:

1、僅僅在appServlet-context.xml 配置<tx:annotation-driven/> ,非子容器加載的實例沒有事務能力

2、在父子容器都配置 <tx:annotation-driven/>:是各自獨立的事務,毫無關係。本質同AOP的原理

總結:

1、避免父子容器擁有共同的實例,是沒有必要的使用方式。

     常見的資源初始化、預熱多次;

     如果父子容器都有實例,而通過SpringUtil 的方式獲取bean,就要看SpringUtil 所在的容器,來獲取對應的bean,也容易混亂

2、事務一般不要放在子容器中,子容器應該僅僅存在 web相關的bean;這也間接說明@Transactional 不應該修飾controller

3、如果希望對子容器的實例擁有事務能力,需要確保<aop:aspectj-autoproxy/> 以及Aspect 配置在子容器中

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