finishBeanFactoryInitialization(beanFactory)源码阅读

传送门

  1. Spring IOC容器初始化源码剖析(一)
  2. Spring IOC容器初始化源码剖析(二)
  3. Spring IOC容器初始化源码剖析(三)

finishBeanFactoryInitialization(beanFactory)

实例化所有剩余的(非lazy-init)单例。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// CONVERSION_SERVICE_BEAN_NAME = conversionService
	// 获取容器中是否存在名为“conversionService”且类型为ConversionService.class的Beandefinition
	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));
	}

	// 若之前没有设置过EmbeddedValueResolver,则设置一个默认的EmbeddedValueResolver,
	// 以用于注解的属性解析。
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
	}

	// 提前初始化LoadTimeWeaverAware
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}

	// 禁用临时类加载器
	beanFactory.setTempClassLoader(null);

	// 允许缓存所有bean定义的元数据
	beanFactory.freezeConfiguration();

	// 实例化所有剩余的(非lazy-init)单例
	beanFactory.preInstantiateSingletons();
}

继续查看preInstantiateSingletons()的内部逻辑。

preInstantiateSingletons

确保所有非惰性单例都被实例化。

// DefaultListableBeanFactory#preInstantiateSingletons
@Override
public void preInstantiateSingletons() throws BeansException {
	if (logger.isTraceEnabled()) {
		logger.trace("Pre-instantiating singletons in " + this);
	}
	// 创建beanDefinitionNames副本
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

	// 触发所有非单例的Bean初始化
	for (String beanName : beanNames) {
		// 根据当前beanName从已经合并的mergedBeanDefinitions中获取,
		// 如果获取到的beandefinition != null 且 不需要合并则直接返回,否则合并后返回
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		// 判断当前BeanDefinition 非抽象 && 单例 && 非懒加载
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			// 判断是否为工厂bean
			if (isFactoryBean(beanName)) {
				// FACTORY_BEAN_PREFIX = &
				// 根据& + beanName获取FactoryBean实例
				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) {
						getBean(beanName);
					}
				}
			}
			else {
				// 根据beanName获取bean实例
				getBean(beanName);
			}
		}
	}

	// 触发实现SmartInitializingSingleton接口的bean的回调。
	for (String beanName : beanNames) {
		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 {
				// 调用实例化后处理
				smartSingleton.afterSingletonsInstantiated();
			}
			smartInitialize.end();
		}
	}
}

大致流程如下:

  1. 创建beanDefinitionNames副本,并开始遍历beanDefinitionNames。可能会有同学忘记了beanDefinitionNames是什么地方add的,可以参考DefaultListableBeanFactory#registerBeanDefinition方法或《Beandefinition是如何创建的》
  2. 根据beanName获取RootBeanDefinition,如果获取到的beandefinition != null 且 不需要合并则直接返回,否则合并后返回。
    protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
    	// Quick check on the concurrent map first, with minimal locking.
    	RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
    	// 检查获取到的mbd != null 且 当前beanDefinition不需要需要重新合并
    	if (mbd != null && !mbd.stale) {
    		return mbd;
    	}
    	// 返回合并后的RootBeanDefinition
    	return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
    }
    
  3. 判断当前RootBeanDefinition是否满足非抽象 && 单例 && 非懒加载,true:走以下逻辑。
  4. isFactoryBean(beanName)判断是否为FactoryBean,true: 获取isEagerInit属性,进一步确认是否立即初始化,false:直接getBean(beanName)实例化。
  5. 单例bean初始化完毕后,判断是否存在实现了SmartInitializingSingleton的bean,存在则调用afterSingletonsInstantiated()

延伸:FactoryBean是一个用来创建对象的工厂Bean(注意与BeanFactory的区别),可以通过实现它来定制实例化(getObject)Bean的逻辑。

public interface FactoryBean<T> {
	
	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

	/**
	 * 获取实例
	 */
	@Nullable
	T getObject() throws Exception;

	/**
	 * 获取类型
	 */
	@Nullable
	Class<?> getObjectType();

	/**
	 * 获取是否为单例
	 */
	default boolean isSingleton() {
		return true;
	}
}

getBean()方法的处理流程是我们必需重点了解的,面试中也会经常提到,该方法将于下文展开阅读。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

人生逆旅我亦行人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值