1. 程式人生 > >spring的父子上下文容器及配置

spring的父子上下文容器及配置

本文由作者張遠道授權網易雲社群釋出。

spring父子容器

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需要對project-service裡的某些方法進行decorate,進行裝飾,比如給CustomerService進行裝飾。裝飾後的類為CachedCustomerService。於是,現在project-api裡面包含兩個CustomerService,一個是來自project-service的CustomerService,另一個是CachedCustomerService。這個時候,如果project-api工程所有的配置檔案都通過一個上下文進行載入,勢必出現問題。因為,project裡的PayService裡通過@Resource標準注入了CustomerService,類似如下

@Serivcepublic class PayService{@Resourceprivate CustomerService cusService;

}

這時,由於上下文在注入customerService屬性的時候,遇到了兩個CustomService。它無法判讀注入哪個Service。 當然了,有人會說,改一下PayService的Resource屬性,指定下具體注入哪個。但是,project-service.jar是第三方庫的話,改動程式碼變得不可行,除非拿到原始碼。

配置父子容器

這個時候,就可以通過父子容器的方式解決這個問題。 將project-service放在父容器中,project-api所有的bean用子容器載入。

假設project-api的上下文配置檔案為project-api.xml,實現方法如下。

1、定義project-total.xml

    <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的上下文配置中如下。

    <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為子容器。在apiContext掃描路徑裡的任務bean都對serviceContext不可見。從而達到隔離的目的

參考列表


更多網易技術、產品、運營經驗分享請訪問網易雲社群

相關文章:
【推薦】 #3.14 Piday#我的圓周率日
【推薦】 玩轉視覺化--來聊聊地圖投影的學問