Spring容器启动AbstractApplicationContext#refresh()#finishBeanFactoryInitialization非懒加载类实例化原理

Spring容器启动之finishBeanFactoryInitialization实例化所有非懒(延迟)加载的Bean流程

实例化所有非懒加载Bean
AbstractApplicationContext#finishBeanFactoryInitialization():
该方法主要负责从spring注册缓存中获取非懒加载类,进行实例化(getBean)

/**
	 * Finish the initialization of this context's bean factory,
	 * initializing all remaining singleton beans.
	 */
	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 bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		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.
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}

方法总结:
1:判断容器三级缓存或BeanDefinition缓存是否存在数据转换器实例或Bean定义,存在则通过getBean() 实例化数据转换器 ConversionService.class,ConversionService是一个服务接口用于类型转换,这也是转换系统的入口点。
2:如果容器中没有后置处理程序,则注册一个默认的嵌入式解析器。(具体负责什么暂时不知道)
3:实例化容器中所有的 LoadTimeWeaverAware接口类型的类,以便尽早注册它们的转换器。LoadTimeWeaverAware是类加载时织入的意思。getBean则是让实现LoadTimeWeaverAware的对象提前实例化。
4:冻结之前beandifinition的配置,留作后面的缓存用
5:实例化所有的non-lazy-init单例,bean真正实例化的时刻到了

真正加载非懒加载Bean具体代码

@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isDebugEnabled()) {
			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.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					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 {
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

DefaultListableBeanFactory#preInstantiateSingletons()总结:

  1. 获取注册Bean定义名称集合
  2. 循环Bean定义集合
    2.1:合并Bean属性,遍历父Bean定义并赋给子Bean定义
    2.2: 判断类是否满足如下条件: 非抽象类 && 单例 && 指定Lazy = false
    2.2.1:否:懒加载类,不进行实例化getBean() 操作,
    2.2.2:是:判断当前Bean是否是FactoryBean,如果是FactoryBean,继续判断FactoryBean是否懒加载,如果非懒加载,实例化FactoryBean 进行getBean()操作
    如果不是FactoryBean,直接对该Bean进行getBean()操作。
  3. 循环BeanDefinition集合,获取Spring三级缓存中存在Bean实例(或者提前暴漏的工厂Bean),在这里只有是非懒加载的Bean都已经通过getBean方法进行了实例化,spring三级缓存中肯定都将上述的非懒加载Bean进行了保存,判断缓存中的Bean是否实现了SmartInitializingSingleton接口,若实现了该接口,执行该Bean的重写方法afterSingletonsInstantiated() ,相当与一个回调函数,可以在这个阶段对自定义Bean做一些特殊的处理流程。

finishBeanFactoryInitialization()大概调用的时序图
FinishBeanFactoryInitialization时序图

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值