Spring源码 - 容器刷新#finishBeanFactoryInitialization()

Spring源码 - 容器刷新finishBeanFactoryInitialization()

Spring版本:Spring 5.3.13-release


# 1、finishBeanFactoryInitialization()初始化剩下的非惰性单实例Bean

AbstractApplicationContext#finishBeanFactoryInitialization()代码:

	/**
	 * Finish the initialization of this context's bean factory,
	 * initializing all remaining singleton beans.
	 *
	 * 完成这个容器的 BeanFactory 初始化工作, 初始化剩下的单实例 Bean
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		// 为上下文初始化类型转换器
		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 BeanFactoryPostProcessor
		// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		// 如果 BeanFactory 之前没有注册嵌入值解析器, 则注册默认的嵌入值解析器, 主要用于注解值的解析
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		// 尽早初始化 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.
		// 冻结所有的 Bean 定义源数据信息。 说明注册的 BeanDefinition 将不被修改或任何进一步的处理
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// 实例化剩余的单实例对象
		beanFactory.preInstantiateSingletons();
	}

上面的代码做了如下几件事情:

  • 首先为当前容器初始化类型转换器ConversionService
  • 冻结所有的BeanDefinition元数据信息。
  • 初始化剩下的非惰性单实例。

其中preInstantiateSingletons为初始化剩余的单实例对象。DefaultListableBeanFactory#preInstantiateSingletons()代码:

@Override
	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.
		// 将所有 BeanDefinition 的名字创建一个集合
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// 触发所有非延迟加载单例 Bean 的初始化, 遍历 BeanDefinition 集合对象
		for (String beanName : beanNames) {

			// Bean 定义信息的公共抽象类是 AbstractBeanDefinition, 普通的 Bean 在 Spring 解析 Bean 定义信息时实例化出来的是 GenericBeanDefinition
			// Spring 上下文包括实例化所有 Bean 使用的 AbstractBeanDefinition 是 RootBeanDefinition
			// 使用 getMergedLocalBeanDefinition 方法做了一次转化, 将非 RootBeanDefinition 转换为 RootBeanDefinition 以供后续操作
			// 注意, 如果当前 BeanDefinition 存在父 BeanDefinition, 会基于父 BeanDefinition 生成一个 RootBeanDefinition, 然后在将调用 OverrideFrom 子 BeanDefinition 的相关属性覆写进去
			// 合并父类 BeanDefinition
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

			// 条件判断。非抽象类 && 单例 && 非懒加载, 则开始创建单例对象, 通过调用 getBean(beanName) 方法进行初始化
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				// 判断是否实现 BeanFactory 接口, 如果实现了 BeanFactory 接口, 判断是否立即初始化
				// 判断 Bean 是否立即初始化, 根据 Bean 是否实现了 SmartFactoryBean 接口并重写内部方法 isEagerInit 并返回 true
				if (isFactoryBean(beanName)) {
					// 根据 & + beanName 来获取 IOC 容器中的 Bean 对象
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					// 进行类型转换
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						// 判断这个 FactoryBean 是否希望立即初始化
						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());
						}
						// 如果希望急切的进行初始化则调用 getBean 方法通过 beanName 获取 Bean 实例对象
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					// 如果 beanName 对应的 Bean 不是 FactoryBean, 只是普通 Bean, 调用 getBean 方法通过 beanName 获取 Bean 实例对象
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		// 遍历 beanNames, 触发所有 SmartInitializingSingleton 后初始化的回调
		for (String beanName : beanNames) {
			// 获取 beanName 对应的单例Bean实例对象
			Object singletonInstance = getSingleton(beanName);
			// 判断获取的 singletonInstance 单例Bean对象是否实现了 SmartInitializingSingleton 接口
			if (singletonInstance instanceof SmartInitializingSingleton) {
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				// 将获取的 singletonInstance 类型转换为 SmartInitializingSingleton 接口
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					// 触发 SmartInitializingSingleton 实现类的 afterSingletonsInstantiated() 方法
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
				smartInitialize.end();
			}
		}
	}

preInstantiateSingletons()方法中,Spring首先会根据BeanName去获取RootBeanDefinition,获取到RootBeanDefinition之后判断当前需要初始化的Bean是否是FactoryBean,如果是FactoryBean并且需要提前初始化则会调用getBean()方法进行实例化。否则直接调用getBean()方法对BeanName所指代的Bean进行初始化。


# 2、MergedBeanDefintion

MeregedBeanDefintion并不是一个官方词汇,这是Spring中对于RootBeanDefinition的变量命名。主要用来表示合并的Bean定义信息Spring中缩写为mbd

对于一个BeanDefinition来说,可能存在以下几种情况:

  • 存在父定义:一个BeanDefinition可能存在父定义信息,这种情况下Spring通常会使用父定义信息的参数构建一个RootBeanDefinition,然后再使用该BeanDefinition的参数对其进行覆盖。
  • 不存在父定义且为RootBeanDefintion:一个BeanDefinition不存在父定义,并且该BeanDefinition的类型是RootBeanDefinition,这种情况下Spring会直接返回该RootBeanDefinition的克隆。
  • 不存在父定义且不为RootBeanDefintion:一个BeanDefinition不存在父定义且不为RootBeanDefinition,这种情况下Spring会使用该BeanDefinition的参数构建一个RootBeanDefinition返回。

可以看出Spring最终处理的BeanDefinition都是RootBeanDefinition

通常SpringBeanFactory解析对Bean的配置时,都是将获取到的BeanDefinition包装成GenericBeanDefinitionScannedGenericBeanDefinition通用的Bean定义信息。但是Spring在对Bean进行初始化时处理的都是RootBeanDefinition。所以Spring会在这里统一将BeanDefinition转换成RootBeanDefinition

我们在应用程序中定义的Bean一般都是第三种情况。如果使用XML配置文件来声明Bean,那么被声明的Bean将会被封装成GenericBeanDefinition。如果使用注解的方式来声明Bean,那么被声明的Bean将会被封装成ScannedGenericBeanDefinition

GitHub源码地址:https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13

备注:此文为笔者学习Spring源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。

你可能感兴趣的:(spring源码,spring,容器,java)