spring總的上下文容器有父子之分,父容器和子容器。 ** 父容器對子容器可見,子容器對父容器不可見 ** 。
對于傳統的spring mvc來說,spring mvc容器為子容器,也就是說ServletDispatcher對應的容器為子容器,而web.xml中通過ConextLoaderListener的contextConfigLocation屬性配置的為父容器。
父子容器的使用場景
父子容器的主要用途是上下文隔離??紤]以下一種場景。
- project-service.jar為服務層模塊。包含一些數據庫service方法。其對應的spring配置文件為project-service.xml。
- project-api為api服務器代碼。它依賴于project-service.jar。其對應的配置文件為project-api.xml。
project-api需要對project-service里的某些方法進行decorate,進行裝飾,比如給CustomerService進行裝飾。裝飾后的類為CachedCustomerService。于是,現在project-api里面包含兩個CustomerService,一個是來自project-service的CustomerService,另一個是CachedCustomerService。這個時候,如果project-api工程所有的配置文件都通過一個上下文進行加載,勢必出現問題(通常的做法是用import標簽全部給import進來)。因為,project里的PayService里通過@Resource標準注入了CustomerService,類似如下
1
2
3
4
5
|
@Serivce public class PayService{ @Resource private CustomerService cusService; } |
解決方式
這時,由于上下文在注入customerService屬性的時候,遇到了兩個CustomService。它無法判讀注入哪個Service。
當然了,有人會說,改一下PayService的Resource屬性,指定下具體注入哪個。但是,project-service.jar是第三方庫的話,改動代碼變得不可行,除非拿到源碼。
這個時候,就可以通過父子容器的方式解決這個問題。
將project-service放在父容器中,project-api所有的bean用子容器加載。
假設project-api的上下文配置文件為project-api.xml,實現方法如下。
1、定義project-total.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
< bean id = "serviceContext" class = "org.springframework.context.support.ClassPathXmlApplicationContext" > < constructor-arg > < value > classpath:project-service.xml </ value > </ constructor-arg > </ bean > < bean id = "apiContext" class = "org.springframework.context.support.ClassPathXmlApplicationContext" > < constructor-arg > < value > classpath:project-api.xml </ value > </ constructor-arg > < constructor-arg > < ref bean = "serviceContext" /> </ constructor-arg > </ bean > |
2、在web.xml的上下文配置中如下。
1
2
3
4
5
6
7
8
9
10
11
12
|
< context-param > < param-name >contextConfigLocation</ param-name > < param-value > classpath*:project-total.xml</ param-value > </ context-param > < listener > < listener-class >org.springframework.web.util.Log4jConfigListener</ listener-class > </ listener > < listener > < listener-class >org.springframework.web.context.ContextLoaderListener</ listener-class > </ listener > |
serviceContext為父容器,apiContext為子容器,從而實現serviceContext看不到apiContext,而apiContext可以看見serviceContext的效果。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://www.jianshu.com/p/d9db47b5fc54