Spring父子容器的关系分析--用实例说话
发布日期:2021-06-30 17:51:00 浏览次数:3 分类:技术文章

本文共 3267 字,大约阅读时间需要 10 分钟。

Spring中父子容器的实现实例Spring的父子容器可以通过ConfigurableApplicationContext或ConfigurableBeanFactory来实现,这两个接口中分别有setParent及setParentBeanFactory方法,可以与当前的子容器进行父子容器关联,这个时候子容器就可以引用父容器中的bean,但是父容器是不能够引用子容器中的bean的,并且各个子容器中定义的bean是互不可见的,这样也可以避免因为不同的插件定义了相同的bean而带来的麻烦。应用场景包括插件或组件的接入,只需要对方提供JAR即可,由父容器进行引导,各个子容器再完成自己的应该完成的工作即可。

以下是一个通过ConfigurableApplicationContext来实现的实例。

//这个类负责启动父容器,也就是我们整个示例程序的入库public class Runner {	public static void main(String[] args){		ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:/spring1.xml");	}}

作为父容器中的Bean
public class ParentClass{	public void print(){		System.out.println("This is parent class.");	}}

PluginLoader 这个类用于对子容器的加载,建立父子容器关系,注意里面的load函数在配置文件里面是init-method,也就是当这个bean初始化完成之后就会调用这个load方法。下面那个setApplicationContext方法spring容器自动调用并自动赋值的,在这个bean初始化之后,load方法之前调用的。

public class PluginLoader implements ApplicationContextAware {	ApplicationContext parentApplicationContext;	ConfigurableApplicationContext childContext;	public void load() {	  	//扫描所有classpath下面的以plugin_开头spring的配置文件进行装配,
		//这里约定所有的子容器插件都必须有一个以plugin_开头的配置文件,并通过这个文件被父容器加载		childContext = new ClassPathXmlApplicationContext("classpath*:/plugin_*.xml");		childContext.setParent(parentApplicationContext);		childContext.refresh();	}	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {		this.parentApplicationContext = applicationContext;	}}

spring1.xml

我准备了两个子容器,并加了互相测试调用的的测试,看子容器是否可以引用另外一个子窗口中的bean,不过因为两个子容器的实现完全相同,只是由1改成2就可以了,以下就只贴出子容器1需要的代码,子容器2的代码类似。

plugin_1.xml

ChildContext1.java 加载自己容器中所有的配置,并与父容器建立父子容器关系
public class ChildContext1 implements ApplicationContextAware {		ApplicationContext parentApplicationContext;	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {	  //父容器中没有建立父子容器关系之前,是获取不到parent的,只有父容器执行refresh方法后,第二次初使化子容器才会获取得到	  //也就是第一次的初使化就不执行了,等父容器中建立好父子容器关系后再进行初使化,因为子容器需要引用父容器中的parentClass		if(applicationContext.getParent()==null){			return;		}		//Get parent application context		this.parentApplicationContext = applicationContext.getParent();		ConfigurableApplicationContext  childContext = new ClassPathXmlApplicationContext("classpath:/child1.xml");		childContext.setParent(this.parentApplicationContext);		childContext.refresh();		ParentClass parentClass = childContext.getBean(ParentClass.class);		Assert.assertNotNull(parentClass);	}}

child1.xml

ChildClass1

下面的afterPropertiesSet方法是指在这个bean所有的属性都设置好之后,就会调用它。spring源码中的解释是:

 * Interface to be implemented by beans that need to react once all their properties have been set by a BeanFactory: for example, to perform custom initialization, or merely to check that all mandatory properties have been set.

public class ChildClass1 implements InitializingBean {  	//这里required加上false,是因为是没有建立父子容器关系之前,这个parentClass是注入不了了的	@Autowired(required = false)	ParentClass parentClass;  	//这里required加上false,是因为子容器之前是不能够相互引用的,只是测试使用。
	//另注:这个类没有放到这里,在子容器2中,这里不贴代码了	@Autowired(required = false)	ChildClass2 childClass2;	public void print() {		if (parentClass != null) {			parentClass.print();		}		System.out.println("This is child class 1");		if (childClass2 != null) {			childClass2.print();		}	}	public void afterPropertiesSet() throws Exception {		print();	}}

本篇博文在 的基础上增加了个人的理解。

转载地址:https://liangyihuai.blog.csdn.net/article/details/48930999 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:spring InitializingBean接口分析
下一篇:一起学spring--spring事件机制--监听器

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月22日 22时50分17秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章