一、介紹
HierarchicalBeanFactory是什麼呢?
spring ioc容器可以建立父子層級管關聯的容器體系,子容器可以訪問父容器的bean,反過來父容器權不能訪問子容器的bean,在容器裏面,bean的id必須唯一,但是子容器可以擁有和父容器相同id的bean,父子容器層級關係增強了spring架構的靈活性和擴展性。
二、測試
接下來我們來測試一下父容器
定義兩個bean
package spring.hierarchical; import java.io.Serializable; /** * @author jiezhou * @CalssName: * @Package com.Hierarchical * @Description: * @date 2020/6/22/10:34 */ public class Child implements Serializable{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Child{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
package spring.hierarchical; import java.io.Serializable; /** * @author jiezhou * @CalssName: Father * @Package com.Hierarchical * @Description: * @date 2020/6/22/10:35 */ public class Father implements Serializable { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Father{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
定義兩個容器對應配置文件
beanChild.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd "> <bean id="child" class="spring.hierarchical.Child" p:name="大頭兒子" p:age="11" /> </beans>
beanFather.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "> <bean id="father" class="spring.hierarchical.Father" p:name="小頭爸爸" p:age="33" /> </beans>
log4j.properties
log4j.rootLogger=ERROR, stdout log4j.logger.xyz.coolblog.chapter1.dao=TRACE log4j.logger.xyz.coolblog.chapter1.dao2=TRACE log4j.logger.xyz.coolblog.chapter4.dao=TRACE log4j.logger.xyz.coolblog.chapter7.dao=TRACE log4j.logger.xyz.coolblog.chapter3.model.dao=TRACE log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
然後在定義測試類
HierarchicalBeanFactoryTest
package spring.hierarchical; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.util.Assert; import java.io.IOException; /** * @author jiezhou * @CalssName: HierarchicalBeanFactoryTest * @Package com.Hierarchical * @Description: spring的父子容器測試 * @date 2020/6/22/10:32 */ public class HierarchicalBeanFactoryTest { /* * 步驟 * 1、建立多個bean.xml 文件對應於多個容器 * * 2、創建父子容器 * 3、HierarchicalBeanFactory添加父容器 * * */ public static void main(String[] args) throws IOException { //創建子容器 /*ClassPathXmlApplicationContext childClassPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath:beanChild.xml"); //創建父容器 ClassPathXmlApplicationContext fatherClassPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath:beanFather.xml"); childClassPathXmlApplicationContext.setParent(fatherClassPathXmlApplicationContext); // BeanFactory factory = child.getParentBeanFactory(); try { //子容器獲取父容器的bean Child child = (Child) childClassPathXmlApplicationContext.getBean("child"); Assert.notNull(child); System.out.println(child.toString()); }catch (Exception e){ e.printStackTrace(); } Father father = (Father) fatherClassPathXmlApplicationContext.getBean("father"); System.out.println(father.toString());*/ //============================================上面的代碼不能正常測試子父容器(HierarchicalBeanFactory)============================================ //child PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver(); Resource resource = pathMatchingResourcePatternResolver.getResource("classpath:beanChild.xml"); DefaultListableBeanFactory childFactory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(childFactory); reader.loadBeanDefinitions(resource); //father PathMatchingResourcePatternResolver fathePathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver(); Resource fatherResource = fathePathMatchingResourcePatternResolver.getResource("classpath:beanFather.xml"); DefaultListableBeanFactory fatherFactory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader fatherReader = new XmlBeanDefinitionReader(fatherFactory); fatherReader.loadBeanDefinitions(fatherResource); childFactory.setParentBeanFactory(fatherFactory); //1、測試父容器調用自己bean和字容器的bean,我們發現父容器不能獲取子容器的bean Father father = fatherFactory.getBean("father",Father.class); System.out.println(father.toString()); Assert.notNull(father); try { Child child = (Child) fatherFactory.getBean("child"); Assert.isNull(child); }catch (Exception e){ e.printStackTrace(); } //2、測試子容器獲取父容器的bean Father bean = childFactory.getBean("father", Father.class); Assert.notNull(bean); System.out.println("我是子容器獲取的父容器的bean"+"\r\n"+bean.toString()); } }
總的結構圖
運行如下:
可以看到報錯是由於父容器獲取子容器的bean時報錯的,而子容器獲取父容器的bean可以正常獲取到。