Spring IOC系列学习笔记八:finishBeanFactoryInitialization

原文地址程序员囧辉大佬

相关文章

Spring IOC系列学习笔记一:前置刷新
Spring IOC系列学习笔记二:obtainFreshBeanFactory方法
Spring IOC系列学习笔记三:parseDefaultElement详解
Spring IOC系列学习笔记四:parseCustomElement解析
Spring IOC系列学习笔记五:context:component-scan 节点解析
Spring IOC系列学习笔记六:invokeBeanFactoryPostProcessors解析
Spring IOC系列学习笔记七:registerBeanPostProcessors
Spring IOC系列学习笔记八:finishBeanFactoryInitialization
Spring IOC系列学习笔记九:getBean方法
Spring IOC系列学习笔记十:createBean方法(上)
Spring IOC系列学习笔记十一:createBean方法(下)
Spring IOC系列学习笔记十二:@Autowire注解


前言

该方法会实例化所有剩余的非懒加载单例 bean。除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。

代码块一:finishBeanFactoryInitialization

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    1、初始化此上下文的转换服务
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }
 
    // Register a default embedded value resolver if no bean post-processor
    // (such as a PropertyPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    2、如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
            @Override
            public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }
 
    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    3、初始化LoadTimeWeaverAware Bean实例对象
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }
 
    // Stop using the temporary ClassLoader for type matching.
    beanFactory.setTempClassLoader(null);
 
    // Allow for caching all bean definition metadata, not expecting further changes.
    4、冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
    beanFactory.freezeConfiguration();
 
    // Instantiate all remaining (non-lazy-init) singletons.
    5、实例化所有剩余(非懒加载)单例对象
    beanFactory.preInstantiateSingletons();
}

5、实例化所有剩余的(非懒加载)单例对象见代码块二

MergedBeanDefinition

直接翻译叫"合并的bean定义"。
对于一个bean来说可能存在一下几种情况。

  1. 该BeanDefinition存在父定义,首先使用父定义的参数来构建一个RootBeanDefinition,然后再用该BeanDefinition 来覆盖这个。

  2. 该BeanDefinition 不存在父定义,并且该BeanDefinition是一个RootBeanDefinition类型,则直接返回该RootBeanDefinition的克隆。

  3. 该BeanDefinition 不存在父定义,但是该BeanDefinition不是一个RootBeanDefinition类型,则该BeanDefinition创建一RootBeanDefinition类型。

    之所以区分出2和3,是因为通常 BeanDefinition 在之前加载到 BeanFactory 中的时候,通常是被封装成 GenericBeanDefinition 或 ScannedGenericBeanDefinition,但是从这边之后 bean 的后续流程处理都是针对 RootBeanDefinition,因此在这边会统一将 BeanDefinition 转换成 RootBeanDefinition。

在我们日常使用的过程中,通常会是上面的第3种情况。如果我们使用 XML 配置来注册 bean,则该 bean 定义会被封装成:GenericBeanDefinition;如果我们使用注解的方式来注册 bean,也就是<context:component-scan /> + @Compoment,则该 bean 定义会被封装成 ScannedGenericBeanDefinition。

具体的代码再getMergedBeanDefinition方法中。截取一点代码如下:

			if (mbd == null) {
				if (bd.getParentName() == null) {
					// Use copy of given root bean definition.
					if (bd instanceof RootBeanDefinition) {
					对应2
						mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
					}
					else {
					对应3
						mbd = new RootBeanDefinition(bd);
					}
				}
				else {
					对应了1
					// 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);
				}

代码块二:preInstantiateSingletons

@Override
	public void preInstantiateSingletons() throws BeansException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("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.
		1、从缓存中获取所有的bean定义的名称
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			2、获取bean对应的MergedBeanDefinition
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			3、不是抽象&&是单例&&不是懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				4、判断bean是否FactoryBean来类型
				if (isFactoryBean(beanName)) {
					5、通过getBean(&beanName)拿到的是FactoryBean本身;
					通过getBean(beanName)拿到的是FactoryBean创建的Bean实例;
					这儿是获取的get(&beanName)
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					5.1、是否需要提前初始化
					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) {
						5.2、提前初始化
						getBean(beanName);
					}
				}
				else {
					6、不是FactoryBean类型直接获取bean实例
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		7、遍历所有的bean执行SmartInitializingSingleton接口的回调
		for (String beanName : beanNames) {
			7.1、获取bean实例
			Object singletonInstance = getSingleton(beanName);
			7.2、判断是否实现了SmartInitializingSingleton接口
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						7.3、执行afterSingletonsInstantiated方法
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

2、获取bean对应的MergedBeanDefinition见代码块三
4、判断bean是否FactoryBean来类型见代码块六
5、getBean方法我们后续再单独讲解。

代码块三:getMergedLocalBeanDefinition

	protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
		// Quick check on the concurrent map first, with minimal locking.
		1、从缓存中获取,如果获取到则直接返回
		RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
		if (mbd != null) {
			return mbd;
		}
		return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
	}

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

		return getMergedBeanDefinition(beanName, bd, null);
	}

	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) {
				2、从缓存中获取bean实例
				mbd = this.mergedBeanDefinitions.get(beanName);
			}

			if (mbd == null) {
				if (bd.getParentName() == null) {
					3.1、没有父定义,就不需要与父定义进行合并
					// Use copy of given root bean definition.
					if (bd instanceof RootBeanDefinition) {
						3.2、该bean是RootBeanDefinition类型,则直接对该bean克隆一个RootBeanDefinition
						mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
					}
					else {
						3.3、对该bean创建一个RootBeanDefinition
						mbd = new RootBeanDefinition(bd);
					}
				}
				else {
					4.1、有父定义,先创建父定义需要与父定义合并。
					// Child bean definition: needs to be merged with parent.
					BeanDefinition pbd;
					try {
						4.2、获取父定义的bean名字
						String parentBeanName = transformedBeanName(bd.getParentName());
						if (!beanName.equals(parentBeanName)) {
							4.3、如果beanName与父定义的bean不同,获取父亲的合并bean,因为父亲可能也有父亲就是该bean的爷爷需要先进行合并
							pbd = getMergedBeanDefinition(parentBeanName);
						}
						else {
							 4.4 如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory,
                       		 只有在存在父BeanFactory的情况下,才允许父定义beanName与自己相同,否则就是将自己设置为父定义
							BeanFactory parent = getParentBeanFactory();
							if (parent instanceof ConfigurableBeanFactory) {
								4.5、如果父BeanFactoryConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition
								反之抛出异常
								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.
					4.6、创建父bean的RootBeanDefinition
					mbd = new RootBeanDefinition(pbd);
					4.7、子覆盖父定义
					mbd.overrideFrom(bd);
				}

				// Set default singleton scope, if not configured before.
				if (!StringUtils.hasLength(mbd.getScope())) {
					5.1、如果没有scope属性则设置成singleton
					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()) {
					5.2、containingBd(顶级的bean)不为空&&containingBd不是单例&&mbd是单例,则将mbd设置成containingBd的scope
					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()) {
					6、放入合并bean的缓存中
					this.mergedBeanDefinitions.put(beanName, mbd);
				}
			}

			return mbd;
		}
	}

4.2、获取父定义的bean名字见代码块四
4.3、如果beanName与父定义的bean不同,获取父亲的合并bean,因为父亲可能也有父亲就是该bean的爷爷需要先进行合并见代码块五
4.6 和 4.7 就是合并操作,也就是我们之前一直说的 MergedBeanDefinition 的由来。
6、将该 beanName 与 MergedBeanDefinition 放到 mergedBeanDefinitions 缓存,后续再走到代码块2时,就会直接返回缓存里的数据。

代码块四:transformedBeanName

	protected String transformedBeanName(String name) {
		1、transformedBeanName删除&为开头的beanName
		2、canonicalName确定原始bean名称,将本地定义的别名解析为规范名称
		return canonicalName(BeanFactoryUtils.transformedBeanName(name));
	}


		public static String transformedBeanName(String name) {
		Assert.notNull(name, "'name' must not be null");
		String beanName = name;
		while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
			beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
		}
		return beanName;
	}

		public String canonicalName(String name) {
		String canonicalName = name;
		// Handle aliasing...
		String resolvedName;
		do {
			resolvedName = this.aliasMap.get(canonicalName);
			if (resolvedName != null) {
				canonicalName = resolvedName;
			}
		}
		while (resolvedName != null);
		return canonicalName;
	}

FactoryBean

在这儿引入有FactoryBean的概念,Spring中一般是通过反射机制利用bean的class属性来进行实例化,而FactoryBean是执行getObject()方法自己去创建bean的实例,所以如果是FactoryBean则只需要实现他的getObject()方法获取实例。

public class AppleFactoryBean implements FactoryBean<Apple> {
 
    @Override
    public Apple getObject() throws Exception {
        Apple apple = new Apple();
        apple.setName("bigApple");
        return apple;
    }
 
    @Override
    public Class<?> getObjectType() {
        return Apple.class;
    }
 
    @Override
    public boolean isSingleton() {
        return true;
    }
}

为了区分FactoryBean和FactoryBean实例,spring对beanName使用&来进行区分,带有&的就是获取FactoryBean本身,不带有&就是获取FactoryBean执行了getObject方法创建的bean实例。

代码块五:getMergedBeanDefinition

	@Override
	public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
		1、解析别名
		String beanName = transformedBeanName(name);

		// Efficiently check whether bean definition exists in this factory.
		2、beanDefinitionMap不包含beanName&&父bean实现ConfigurableBeanFactory
		  则获取父BeanFactory去获取beanName的MergedBeanDefinition
		if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
			return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
		}
		// Resolve merged bean definition locally.
		3、在当前BeanFactory中解析beanName的MergedBeanDefinition
		return getMergedLocalBeanDefinition(beanName);
	}

父 BeanFactory

在 Spring 中可能存在多个 BeanFactory,多个 BeanFactory 可能存在 “父工厂” 与 “子工厂” 的关系。最常见的例子就是:Spring MVC 的 BeanFactory 和 Spring 的 BeanFactory,通常情况下,Spring 的 BeanFactory 是 “父工厂”,Spring MVC 的 BeanFactory 是 “子工厂”,在 Spring 中,子工厂可以使用父工厂的 BeanDefinition,因而,如果在当前 BeanFactory 中找不到,而又存在父工厂,则会去父工厂中查找。

我们回到代码块二继续执行介绍4进入代码块六

代码块六:isFactoryBean

	@Override
	public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
		1、解析别名
		String beanName = transformedBeanName(name);
		2、获取bean的实例对象
		Object beanInstance = getSingleton(beanName, false);
		if (beanInstance != null) {
			return (beanInstance instanceof FactoryBean);
		}

		// No singleton instance found -> check bean definition.
		3、缓存中不存在beanName&&BeanFactory实现了ConfigurableBeanFactory
		if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
			// No bean definition found in this factory -> delegate to parent.
			3.1、判断父beanFactory是不是FactoryBean
			return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
		}
		4、通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean
		return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
	}

2、获取bean的实例对象见代码块七
4、通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean见代码块八

代码块七:getSingleton

	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		1、从单例缓存中获取beanName实例
		Object singletonObject = this.singletonObjects.get(beanName);
		2、singletonObject为空&&单例的bean正在被创建
		if (singletonObject为空&& == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				3、从早期单例对象缓存中获取单例对象(之所称成为早期单例对象,是因为earlySingletonObjects里
            	  的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作)
				singletonObject = this.earlySingletonObjects.get(beanName);
				4、singletonObject为null&&允许早期曝光
				if (singletonObject == null && allowEarlyReference) {
					5、从单例工厂中获取beanName的ObjectFactory
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						6、单例工厂执行getObject获取bean的实例
						singletonObject = singletonFactory.getObject();
						7、放入到早期曝光的缓存中
						this.earlySingletonObjects.put(beanName, singletonObject);
						8、已经实例化,从单例工厂中移除
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		9、返回实例
		return singletonObject;
	}

这个方法非常重要是解决循环依赖的核心代码

解决循环引用逻辑:使用构造函数创建一个 “不完整” 的 bean 实例(之所以说不完整,是因为此时该 bean 实例还未初始化),并且提前曝光该 bean 实例的 ObjectFactory(提前曝光就是将 ObjectFactory 放到 singletonFactories 缓存),通过 ObjectFactory 我们可以拿到该 bean 实例的引用,如果出现循环引用,我们可以通过缓存中的 ObjectFactory 来拿到 bean 实例,从而避免出现循环引用导致的死循环。这边通过缓存中的 ObjectFactory 拿到的 bean 实例虽然拿到的是 “不完整” 的 bean 实例,但是由于是单例,所以后续初始化完成后,该 bean 实例的引用地址并不会变,所以最终我们看到的还是完整 bean 实例。

另外这个代码块中引进了4个重要缓存:

  1. singletonObjects:beanName->单例bean实例
  2. earlySingletonObjects:beanName->单例bean实例,早期曝光的单例bean,还未进行属性填充初始化。
  3. singletonFactories:beanName->ObjectFactory
  4. singletonsCurrentlyInCreation :正在创建单例beanName的beanName集合。

singletonObjects 、earlySingletonObjects、singletonFactories构成了一个三级缓存的概念

代码块八:isFactoryBean

protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
    // 1.拿到beanName对应的Bean实例的类型
    Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
    // 2.返回beanType是否为FactoryBean本身、子类或子接口
    return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
}

1.拿到beanName对应的Bean实例的类型见代码块九,这儿执行的是AbstractAutowireCapableBeanFactory的predictBeanType方法。

代码块九:predictBeanType

@Override
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
    // 1.拿到beanName的类型
    Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);
 
    // Apply SmartInstantiationAwareBeanPostProcessors to predict the
    // eventual type after a before-instantiation shortcut.
    // 2.应用SmartInstantiationAwareBeanPostProcessors后置处理器,来预测实例化的最终类型,
    // SmartInstantiationAwareBeanPostProcessors继承了InstantiationAwareBeanPostProcessor,
    // InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法可以改变Bean实例的类型,
    // 而SmartInstantiationAwareBeanPostProcessors的predictBeanType方法可以预测这个类型
    if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                // 3.调用predictBeanType方法
                Class<?> predicted = ibp.predictBeanType(targetType, beanName);
                if (predicted != null && (typesToMatch.length != 1 || FactoryBean.class != typesToMatch[0] ||
                        FactoryBean.class.isAssignableFrom(predicted))) {
                    // 4.如果predicted不为空 && (typesToMatch长度不为1 || typesToMatch[0]不为FactoryBean.class ||
                    // predicted是FactoryBean本身、子类或子接口),则返回predicted
                    return predicted;
                }
            }
        }
    }
    // 5.否则返回beanName的类型
    return targetType;
}

总结

本文主要执行了创建bean之前的一些准备操作,引入FactoryBean这一个特殊的bean,获取BeanDefinition的MergedBeanDefinition,转换成RootBeanDefinition。
引入一下几个缓存:

  • mergedBeanDefinitions:beanName->合并的bean定义。
  • singletonObjects:beanName->单例bean实例
  • earlySingletonObjects:beanName->单例bean实例,早期曝光的单例bean,还未进行属性填充初始化。
  • singletonFactories:beanName->ObjectFactory
  • singletonsCurrentlyInCreation :正在创建单例beanName的beanName集合。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值
>