栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

资深小白谈spring(十七):BeanDefinition的合并原理

Java 更新时间:发布时间: 百科书网 趣学号

资深小白谈spring(十七):preInstantiateSingletons

序言:前面用了比较多的章节讲解了spring从创建容器、扫描得到BeanDefinitionMap、BeanFactoryPostProcessor的初始化及其方法的执行以及BeanPostProcessor的初始化和注册等等,接下来将进入spring framework的重中之重:IOC和AOP的源码讲解。本节开始将正式开始讲解spring bean创建的一系列生命周期,内容精彩不要错过哦。

1、在finishBeanFactoryInialization方法中,调用了beanFactory的preInstantiateSingletons方法。从注释上就指定这个方法是用来创建非懒加载的单例bean。2、spring遍历beanDefinitionNames拿到beanName,首先做的是合并BeanDefinition。为什么要合并呢?这是因为spring的BeanDefinition支持继承,BeanDefinition的继承能够简化代码和配置。

3、下面举个BeanDefinition合并的例子,以便更好地理解这个合并原理。首先定义一个父类parent和子类son,他们都有属性name。
4、然后在xml上对这两个bean进行定义,parent为抽象类,son的parent属性执行parent,parent的bean定义中给name赋值。
5、打印son的name属性,可以看到son的name属性也被赋值成了people。

6、合并前先从mergedBeanDefinitions容器中取,如果有就直接返回,如果没有才进行合并
7、这里的代码也不难也很容易阅读,主要做的也就是,获取到当前BeanDefintion的parent,然后将当前bd的内容覆盖parent的内容,然后放入一个rootBeanDefintion进行返,所以基于这个特性我们可以总结到,这里子BeanDefinition是可以覆盖父Beanfinition的属性,也就是说,如果子Beanfinition和父Beanfinition都有A属性,那么后面的生命周期中会以子Beanfinition的A属性为准。

	protected RootBeanDefinition getMergedBeanDefinition(
			String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
			throws BeanDefinitionStoreException {

		synchronized (this.mergedBeanDefinitions) {
			RootBeanDefinition mbd = null;

			// Check with full lock now in order to enforce the same merged instance.
			if (containingBd == null) {
				mbd = this.mergedBeanDefinitions.get(beanName);
			}

			if (mbd == null) {
				if (bd.getParentName() == null) {
					// Use copy of given root bean definition.
					if (bd instanceof RootBeanDefinition) {
						mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
					}
					else {
						mbd = new RootBeanDefinition(bd);
					}
				}
				else {
					// Child bean definition: needs to be merged with parent.
					BeanDefinition pbd;
					try {
						String parentBeanName = transformedBeanName(bd.getParentName());
						if (!beanName.equals(parentBeanName)) {
							pbd = getMergedBeanDefinition(parentBeanName);
						}
						else {
							BeanFactory parent = getParentBeanFactory();
							if (parent instanceof ConfigurableBeanFactory) {
								pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
							}
							else {
								throw new NoSuchBeanDefinitionException(parentBeanName,
										"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
										"': cannot be resolved without an AbstractBeanFactory parent");
							}
						}
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
								"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
					}
					// Deep copy with overridden values.
					mbd = new RootBeanDefinition(pbd);
					mbd.overrideFrom(bd);
				}

				// Set default singleton scope, if not configured before.
				if (!StringUtils.hasLength(mbd.getScope())) {
					mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
				}

				// A bean contained in a non-singleton bean cannot be a singleton itself.
				// Let's correct this on the fly here, since this might be the result of
				// parent-child merging for the outer bean, in which case the original inner bean
				// definition will not have inherited the merged outer bean's singleton status.
				if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
					mbd.setScope(containingBd.getScope());
				}

				// Cache the merged bean definition for the time being
				// (it might still get re-merged later on in order to pick up metadata changes)
				if (containingBd == null && isCacheBeanmetadata()) {
					this.mergedBeanDefinitions.put(beanName, mbd);
				}
			}

			return mbd;
		}
	}

8、结语:本节介绍了BeanDefinition的合并,下一节将讲spring的循环依赖。

  • 上一篇:资深小白谈spring(十六):registerBeanPostProcessors
  • 下一篇:资深小白谈spring(十八):getBean
转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/274947.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号