一、介绍
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可以正常获取到。