spring中父子容器的實現

轉載:http://blog.csdn.net/fenglibing/article/details/8597789

 

Spring中父子容器的實現實例Spring的父子容器可以通過ConfigurableApplicationContext或ConfigurableBeanFactory來實現,這兩個接口中分別有setParent及setParentBeanFactory方法,可以與當前的子容器進行父子容器關聯,這個時候子容器就可以引用父容器中的bean,但是父容器是不能夠引用子容器中的bean的,並且各個子容器中定義的bean是互不可見的,這樣也可以避免因爲不同的插件定義了相同的bean而帶來的麻煩。應用場景包括插件或組件的接入,只需要對方提供JAR即可,由父容器進行引導,各個子容器再完成自己的應該完成的工作即可。

以下是一個通過ConfigurableApplicationContext來實現的實例。

1、父容器需要的幾個文件:

1)、Runner.java

[java] view plaincopy
 
  1. //這個類負責啓動父容器  
  2. public class Runner {  
  3.     public static void main(String[] args){  
  4.         ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:/spring1.xml");  
  5.     }  
  6. }  

2)、ParentClass 這個類主要用於測試子容器是否可以獲取父容器中定義的bean

[java] view plaincopy
 
  1. public class ParentClass{  
  2.     public void print(){  
  3.         System.out.println("This is parent class.");  
  4.     }  
  5. }  

3)、PluginLoader 這個類用於對子容器的加載,建立父子容器關係

[java] view plaincopy
 
  1. public class PluginLoader implements ApplicationContextAware {  
  2.     ApplicationContext parentApplicationContext;  
  3.     ConfigurableApplicationContext childContext;  
  4.   
  5.     public void load() {  
  6.       //掃描所有classpath下面的以plugin_開頭spring的配置文件進行裝配,這裏約定所有的子容器插件都必須有一個以plugin_開頭的配置文件,並通過這個文件被父容器加載  
  7.         childContext = new ClassPathXmlApplicationContext("classpath*:/plugin_*.xml");  
  8.         childContext.setParent(parentApplicationContext);  
  9.         childContext.refresh();  
  10.     }  
  11.   
  12.     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
  13.         this.parentApplicationContext = applicationContext;  
  14.     }  
  15. }  

4)、spring1.xml

 

[html] view plaincopy
 
  1. <bean id="parentClass" class="com.test1.ParentClass"></bean>  
  2. <bean id="pluginLoader" class="com.test1.PluginLoader" init-method="load"></bean>  



 

簡單的父容器就只需要這麼幾個類了。

2、子容器1需要的幾個文件

我準備了兩個子容器,並加了互相測試調用的的測試,看子容器是否可以引用另外一個子窗口中的bean,不過因爲兩個子容器的實現完全相同,只是由1改成2就可以了,以下就只貼出子容器1需要的代碼,子容器2的代碼類似。

1)、plugin_1.xml 這個類是約定好必須存在的,由容器進行引導

 

[html] view plaincopy
 
  1. <pre name="code" class="html"><bean id="childContext1" class="com.test1.child.ChildContext1"></bean>  

 

2)、ChildContext1.java 加載自己容器中所有的配置,並與父容器建立父子容器關係

[java] view plaincopy
 
  1. public class ChildContext1 implements ApplicationContextAware {  
  2.       
  3.     ApplicationContext parentApplicationContext;  
  4.   
  5.     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
  6.       //父容器中沒有建立父子容器關係之前,是獲取不到parent的,只有父容器執行refresh方法後,第二次初使化子容器纔會獲取得到  
  7.       //也就是第一次的初使化就不執行了,等父容器中建立好父子容器關係後再進行初使化,因爲子容器需要引用父容器中的parentClass  
  8.         if(applicationContext.getParent()==null){  
  9.             return;  
  10.         }  
  11.         //Get parent application context  
  12.         this.parentApplicationContext = applicationContext.getParent();  
  13.   
  14.         ConfigurableApplicationContext  childContext = new ClassPathXmlApplicationContext("classpath:/child1.xml");  
  15.         childContext.setParent(this.parentApplicationContext);  
  16.         childContext.refresh();  
  17.         ParentClass parentClass = childContext.getBean(ParentClass.class);  
  18.         Assert.assertNotNull(parentClass);  
  19.     }  
  20.   
  21. }  

3)、child1.xml

 

[html] view plaincopy
 
  1. <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">   
  2. <bean id="childClass1" class="com.test1.child.ChildClass1">  

 

4)、ChildClass1

[java] view plaincopy
 
  1. public class ChildClass1 implements InitializingBean {  
  2.   //這裏required加上false,是因爲是沒有建立父子容器關係之前,這個parentClass是注入不了了的  
  3.     @Autowired(required = false)  
  4.     ParentClass parentClass;  
  5.   
  6.   //這裏required加上false,是因爲子容器之前是不能夠相互引用的,只是測試使用。另注:這個類沒有放到這裏,在子容器2中,這裏不貼代碼了  
  7.     @Autowired(required = false)  
  8.     ChildClass2 childClass2;  
  9.   
  10.     public void print() {  
  11.         if (parentClass != null) {  
  12.             parentClass.print();  
  13.         }  
  14.         System.out.println("This is child class 1");  
  15.         if (childClass2 != null) {  
  16.             childClass2.print();  
  17.         }  
  18.     }  
  19.   
  20.     public void afterPropertiesSet() throws Exception {  
  21.         print();  
  22.   
  23.     }  
  24. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章