SpringApplication上下文刷新第十一步finishBeanFactoryInitialization

在该步SpringApplication完成了 非单例 非懒加载(通过FactoryBean定义的Bean,并且是懒加载的如果没人使用,就先不会实例化。只会到使用的时候才实例化) Bean的加载工作.并在加载前提前加入了为AOP功能切入点织入通知的类以及设置标志位告知应用不许修改BeanDefinition

这里会跑回到AbstractAutowireCapableBeanFactory.doCreateBean方法上.又复习了一次Bean生命周期

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// 加载初始化类型转换Bean.这里未加载
	// 已经在run方法prepareContext步加载过了(postProcessApplicationContext方法中)
	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));
	}

	// 实例化LoadTimeWeaverAware接口的bean,用于ApsectJ的类加载期织入的处理,提前加载是为了AOP功能,能为切入点织入通知.创建动态代理类
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}

	// 临时加载器置空,前期用临时加载器进行类型匹配工作
	beanFactory.setTempClassLoader(null);

	// beanDefinition冻结标志位设置为True.保存beanDefinition名称快照,因为马上要加载Bean了不希望这些beanDefinition被修改
	beanFactory.freezeConfiguration();

	// 实例化所有非懒加载单例Bean
	beanFactory.preInstantiateSingletons();
}

1. DefaultListableBeanFactory.preInstantiateSingletons

获取所有的Bean名称,对单例、非懒加载的Bean进行加载(通过AbstractBeanFactory.getBean()方法).其中特别对实现SmartFactoryBean的工厂Bean做了特殊校验,如果该工厂Bean要加载的Bean是非懒加载的则立即加载出来.

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

	// 获取所有Bean名称,迭代进行Bean加载.原来的作为缓存
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

	// Bean加载步骤
	for (String beanName : beanNames) {
	   // 获取该Bean的Bean定义,只能是单例、非懒加载的Bean能被加载
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
		    // 如果是工厂Bean是SmartFactoryBean类型判断该工厂要创建的单例Bean是否是懒加载
		    // 不是懒加载则立即加载出来.否则等需要时再加载
			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 {
			    // 如果不是工厂Bean则直接加载
				getBean(beanName);
			}
		}
	}

	// 执行SmartInitializingSingleton类型单例Bean的回调.类似于ContextRefreshedEvent事件监听器.但实现方便
	// 所有单例非懒加载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();
		}
	}
}

2. AbstractBeanFactory.getBean()方法

该方法在工厂中负责获取容器中的Bean以及当Bean不存在时去加载Bean到容器中.这里getSingleton又涉及到了循环依赖,三级缓存相关知识.

public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}


protected <T> T doGetBean(
		String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
		throws BeansException {

    // 获取Bean原始名称,比如工厂Bean哪里加了&则会去除,多层别名则会获取最原始的名称
	String beanName = transformedBeanName(name);
	Object beanInstance;

	// 这里从容器缓存中找是否已经创建过/正在创建中(循环依赖),没有创建过则从else中执行重载方法进行对象创建.
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null && args == null) {
		if (logger.isTraceEnabled()) {
		    // 日志说明: 如果在singletonsCurrentlyInCreation容器中找到了则表示是未完全初始化的Bean,它只是循环引用的结果
			if (isSingletonCurrentlyInCreation(beanName)) {
				logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
						"' that is not fully initialized yet - a consequence of a circular reference");
			}
			else {
				logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}
		// 获取完整Bean对象,如果不是FactoryBean则会返回本身.否则则通过工厂Bean创建Bean
		// 执行PostProcessorsAfterInitialization方法
		beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}
    // 如果在上面缓存中没有,也没有该它的BeanFactory,就自行创建
	else {
		// 原型对象不允许循环创建,检查下是否是原型对象并且正在创建,是则抛出异常
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// 检查是否该BeanDefinition存在于父容器中/如果父级容器存在则交由父级容器尝试加载
		// 这步就是套娃检查,父容器能加载就让父容器加载了
		BeanFactory parentBeanFactory = getParentBeanFactory();
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			String nameToLookup = originalBeanName(name);
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
						nameToLookup, requiredType, args, typeCheckOnly);
			}
			else if (args != null) {
				// Delegation to parent with explicit args.
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else if (requiredType != null) {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
			else {
				return (T) parentBeanFactory.getBean(nameToLookup);
			}
		}
        
        // 仅类型检查标志位被修改过后,则标记下该Bean已经被创建过了
		if (!typeCheckOnly) {
			markBeanAsCreated(beanName);
		}

		StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
				.tag("beanName", name);
		try {
			if (requiredType != null) {
				beanCreation.tag("beanType", requiredType::toString);
			}
			// 获取BeanDefinition.准备自己创建
			RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			// 查看该类是否是抽象类,是的话就抛出异常
			checkMergedBeanDefinition(mbd, beanName, args);

			// 处理预先加载@DependsOn标记的依赖Bean,如果在这里有循环依赖则直接抛出异常
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dep : dependsOn) {
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					registerDependentBean(dep, beanName);
					try {
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}

			// 创建单例Bean,这里lambda表达式中createBean是调用到AbstractAutowireCapableBeanFactory.doCreateBean方法.执行Bean创建的生命周期
			// AbstractBeanFactory是它的父类.所以直接使用createBean没有毛病.本身就是它自己定义的方法.执行时也是子类在执行
			// 判断该Bean是单例还是多例,单例则执行doCreateBean方法.获取单例Bean并进行Bean工厂注册
			// 如果是多例则调用beforePrototypeCreation和afterPrototypeCreation来记录在创建的状态,防止循环引用
			if (mbd.isSingleton()) {
				sharedInstance = getSingleton(beanName, () -> {
					try {
						return createBean(beanName, mbd, args);
					}
					catch (BeansException ex) {
						// Explicitly remove instance from singleton cache: It might have been put there
						// eagerly by the creation process, to allow for circular reference resolution.
						// Also remove any beans that received a temporary reference to the bean.
						destroySingleton(beanName);
						throw ex;
					}
				});
				beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}

			else if (mbd.isPrototype()) {
				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
				beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}

			else {
				String scopeName = mbd.getScope();
				if (!StringUtils.hasLength(scopeName)) {
					throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
				}
				Scope scope = this.scopes.get(scopeName);
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, () -> {
						beforePrototypeCreation(beanName);
						try {
							return createBean(beanName, mbd, args);
						}
						finally {
							afterPrototypeCreation(beanName);
						}
					});
					beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				}
				catch (IllegalStateException ex) {
					throw new ScopeNotActiveException(beanName, scopeName, ex);
				}
			}
		}
		catch (BeansException ex) {
			beanCreation.tag("exception", ex.getClass().toString());
			beanCreation.tag("message", String.valueOf(ex.getMessage()));
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
		finally {
			beanCreation.end();
		}
	}
    
    // 最后对Bean类型做一个适配,不符合的类型则做一下转换.
	return adaptBeanInstance(name, beanInstance, requiredType);
}

getMergedLocalBeanDefinition(String beanName)方法

Bean定义公共的抽象类是AbstractBeanDefinition,普通的Bean在Spring加载Bean定义的时候,实例化出来的是GenericBeanDefinition,而Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition,这时候就使用getMergedLocalBeanDefinition方法做了一次转化,将非RootBeanDefinition转换为RootBeanDefinition以供后续操作
getMergedLocalBeanDefinition方法的作用就是获取缓存的BeanDefinition对象并合并其父类和本身的属性

3. DefaultSingletonBeanRegistry.getSingleton

该方法主要是做了bean创建的重复校验,Bean添加到容器中前后都判断是否重复创建了,如果有重复创建则抛出异常beforeSingletonCreation(beanName);,afterSingletonCreation(beanName);.如果容器中还是没有则进行创建该Bean的操作(Bean生命周期),创建完后加入容器中.上面lambda函数就是singletonFactory.getObject();方法

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(beanName, "Bean name must not be null");
	synchronized (this.singletonObjects) {
	    // 从缓存中获取(上面获取过一次的,这里是双从判定)
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null) {
			if (this.singletonsCurrentlyInDestruction) {
				throw new BeanCreationNotAllowedException(beanName,
						"Singleton bean creation not allowed while singletons of this factory are in destruction " +
						"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
			}
			beforeSingletonCreation(beanName);
			boolean newSingleton = false;
			boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet<>();
			}
			try {
			    // 把这个实例生成出来,并且标志位设为true. 上面lambda表达式就是实现的这个方法.
				singletonObject = singletonFactory.getObject();
				newSingleton = true;
			}
			catch (IllegalStateException ex) {
				// 创建异常了则判断是否已经有人加入过该Bean了
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					throw ex;
				}
			}
			catch (BeanCreationException ex) {
				if (recordSuppressedExceptions) {
					for (Exception suppressedException : this.suppressedExceptions) {
						ex.addRelatedCause(suppressedException);
					}
				}
				throw ex;
			}
			finally {
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = null;
				}
				afterSingletonCreation(beanName);
			}
			// !最后将这个已经创建好的Bean加入一级缓存容器中,删除二三级缓存中对该Bean的缓存
			if (newSingleton) {
				addSingleton(beanName, singletonObject);
			}
		}
		return singletonObject;
	}
}

AbstractAutowireCapableBeanFactory.createBean

他会去调用doCreateBean方法,来实现整个Bean的实例化、初始化的生命周期流程
.所以这里可以跳过.直接看doCreateBean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	RootBeanDefinition mbdToUse = mbd;

	// 确认对应bean的Class已经加载解析过了
	// 做一份副本用来进行类动态解析
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	// Prepare method overrides.
	try {
	    // 可不看,通过配置文件进行方法重写,实现注入
		mbdToUse.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

	try {
		// 通过BeanPostProcessors来创建Bean的代理对象
		// 该步执行InstantiationAwareBeanPostProcessor接口的Bean实例化前方法
		// 具体逻辑是判断当前Spring容器是否注册了实现了InstantiationAwareBeanPostProcessor接口的后置处理器如果有
		// 则依次调用其中的applyBeanPostProcessorsBeforeInstantiation方法
		// 如果中间任意一个方法返回不为null,直接结束调用
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		// 如果不为空,说明提前生成了实例,直接返回
		if (bean != null) {
			return bean;
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
				"BeanPostProcessor before instantiation of bean failed", ex);
	}

	try {
	    // Bean创建以及生命周期在这个方法中.新开一个文章介绍
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isTraceEnabled()) {
			logger.trace("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
	catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
		// A previously detected exception with proper bean creation context already,
		// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
		throw ex;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
	}
}

参考

spring 源码探索-- 静态AOP代理
AbstractApplicationContext.refresh方法
AbstractBeanFactory#getBean()、doGetBean完成Bean的初始化、实例化,以及BeanPostProcessor后置处理器
AbstractApplicationContext之refresh
【小家Spring】Spring IOC容器启动流程 AbstractApplicationContext#refresh()方法源码分析(二),Spring容器启动/刷新的完整总结

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值