spring源码之RootBeanDefinition合并Bean

        spring启动过程中,当bean已经被扫描到spring容器里面时,他会执行refresh()方法,在该方法中会执行finishBeanFactoryInitialization(beanFactory);来实例化所有非懒加载的单例bean,该方法中核心就是执行beanFactory.preInstantiateSingletons(); 实例化非懒加载的单例Bean,下面就是该方法的源码:

public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			// 合并有父类的BeanDefinition,也就是定义的属性进行合并,假设自己定义了则覆盖,否则就拿父类的比如scope属性
			//合并之后是生成第三个新的RootBeanDefinition对象
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//判断根据名字得到的BeanDefinition是否是抽象的BeanDefinition(不是指抽象类,比如用xml的方式定义bean就会有一个abstract属性)
			//比如父类bean是抽象的,设置为scope属性设置为prototype,那么继承他的子类也是prototype
			// 是否是单例、是否是懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//判断beanName表示的bean是不是一个FactoryBean
				if (isFactoryBean(beanName)) {
					// 是,则创建FactoryBean对象放入单例池里面。FACTORY_BEAN_PREFIX相当于"&"
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							// 创建真正的Bean对象(getObject()返回的对象)
							getBean(beanName);
						}
					}
				}
				// 不是factoryBean则直接(调用doCreateBean)创建Bean对象
				else {
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			//所有的非懒加载单例Bean都创建完了后会放到单例池里面去,根据名字从单例池拿单例对象
			//这里主要是判断是否出现了循环依赖以及怎么处理
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					//所有非懒加载的单例bean创建完之后调用该方法
					smartSingleton.afterSingletonsInstantiated();
				}
				smartInitialize.end();
			}
		}
	}

首先会拿到所有加载的bean的名字的集合,然后遍历这些beanName,之后调用getMergedLocalBeanDefinition方法对bean进行合并,比如:我们在xml里面定义了一个bean,为他指定了一个parent父bean,那么该方法就会对这两个bean进行合并生成第三个bean。该方法中会执行getMergedBeanDefinition(beanName, getBeanDefinition(beanName));首先beanDefinitionMap里面拿出bean然后执行getMergedBeanDefinition方法进行合并

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

		synchronized (this.mergedBeanDefinitions) {
			RootBeanDefinition mbd = null;
			RootBeanDefinition previous = 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 || mbd.stale) {
				previous = mbd;
				//当前bean是否指定parent
				//如果没有
				if (bd.getParentName() == null) {
					// Use copy of given root bean definition.
					//没有指定判断是否是root,是的话就克隆一个,将属性进行复制,也就是生成一个新的
					if (bd instanceof RootBeanDefinition) {
						mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
					}
					else {
						//构造新的属性赋值
						mbd = new RootBeanDefinition(bd);
					}
				}
				//如果有指定parent
				else {
					// Child bean definition: needs to be merged with parent.
					// pbd表示parentBeanDefinition
					BeanDefinition pbd;
					try {
						//拿到parent的Bean的名字
						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 a ConfigurableBeanFactory parent");
							}
						}
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
								"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
					}

					// Deep copy with overridden values.
					// 子BeanDefinition的属性覆盖父BeanDefinition的属性,这就是合并
					mbd = new RootBeanDefinition(pbd);
					//设置属性,判断子bean有没有设置自己的beanName,scope等,如果定义了则直接把自己的设置进去
					//否则就用自己的
					mbd.overrideFrom(bd);
				}

				// Set default singleton scope, if not configured before.
				if (!StringUtils.hasLength(mbd.getScope())) {
					mbd.setScope(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()) {

					//将合并后的BeanDefinition存进来
					this.mergedBeanDefinitions.put(beanName, mbd);
				}
			}
			if (previous != null) {
				copyRelevantMergedBeanDefinitionCaches(previous, mbd);
			}
			return mbd;
		}
	}

该源码逻辑就是,首先如果当前bean没有指定parent,则判断是不是root,也就是根bean,是的话就克隆一份自己的并且将属性进行复制。

如果有指定的parent的话就会调用transformedBeanName方法来处理bean的名字,比如我们在getBean()的时候传的参数里面有“&xxx”,我们最终期望得到的bean的名字肯定不是带有"&"的,该方法就是去除"&",之后就会进行递归,就是自己的父类也可能有指定了父类,然后调用相同的方法再次执行上面的逻辑。

最终执行这两个方法:

	mbd = new RootBeanDefinition(pbd);
					

	mbd.overrideFrom(bd);

主要就判断子bean有没有设置自己的属性,没有的话就把父类的属性设置进去,有的话则覆盖父类的属性并且把自己的设置进去。比如父bean设置的scope是prototype,子bean没有设置scope那么合并后的bean的scope就是父类的prototype,若子类将scope设置成了singleton那么合并后的bean的scope就是子类的singleton。

合并完之后就会创建调用getBean()方法创建bean,也就是执行bean的生命周期,其中就包括了初始化,属性赋值,实例化前,实例化,实例化之后。最终所有的非懒加载单例Bean都创建完了后会放到单例池里面去,然后执行下面的方法

Object singletonInstance = getSingleton(beanName);

该方法主要是判断是否出现了循环依赖,是否正在创建,以及出现了循环依赖后使用三级缓存处理的过程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鹏之翼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值