Spring中Bean的实例化过程

文章目录

  • 一、回顾BeanDefinition注册
    • 1.BeanDefinition是什么?
    • 2.注册BeanDefinition逻辑回顾
    • 3.为什么回顾BeanDefinition注册相关内容?
  • 二、Bean的实例化过程
    • 1.Bean实例化方法入口描述
    • 2.图解Bean实例化流程
    • 3.论BeanPostProcessor
    • 4.源码解析Bean的实例化过程
      • 4.1 找到入口代码
      • 4.2 不断的getBean直到doGetBean
      • 4.3 不断的createBean最后doCreateBean
      • 4.4 有参和无参构造函数的初始化
      • 4.5 类注解信息收集
      • 4.6 单例Bean提前暴露到三级缓存
      • 4.7 DI依赖注入
      • 4.8 后置初始化和AOP代理
  • 三、总结

一、回顾BeanDefinition注册

工厂的创建和注册obtainFreshBeanFactory

// refresh中的关键业务方法
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

Spring容器初始化的时候会有一个refresh()方法,在该方法中会调用obtainFreshBeanFactory(),先进行容器的工厂的初始化,默认的工厂是DefaultListableBeanFactory类的实例。
ClassPathXmlApplicationContext这个容器就是在这个方法中进行的XML解析和扫描完成BeanDefinition的注册的。

1.BeanDefinition是什么?

BeanDefinition中包含你对这个Bean相关的配置,class,id,name,property,construct-args等内容。这些内容会被统一包装成一个对象并放入Map中记录下来,这个对象就是BeanDefinition对象,这个map就是beanDefinitionMap。

2.注册BeanDefinition逻辑回顾

在注册BeanDefinition的时候,是把id当作BeanDefinitionMap的key,把待注册的BeanDefinition对象当value,然后把id放入beanDefinitionNames这个list中。

beanDefinitionMap:是用来存储BeanDefinition的映射。
beanDefinitionNames:是用来存储Bean的名称。

3.为什么回顾BeanDefinition注册相关内容?

Bean的实例化依赖注册好的BeanDefinition相关的内容,比如上述提到的beanDefinitionNames集合,它存储了Spring维护的全部的BeanDefinition的名称,Bean实例化首先要知道那些的Bean需要被实例化,故会遍历这个beanDefinitionNames集合,得到bean的名字一个一个去实例化。

beanDefinitionMap是BeanName和BeanDefinition的映射,我们可以通过遍历得到的BeanName去寻找BeanDefinition,在BeanDefinition中包含了一个Bean实例化需要的全部信息,拿着这个信息,我们就可以去漫谈Bean的实例化流程了。

二、Bean的实例化过程

1.Bean实例化方法入口描述

在refresh()方法中还有finishBeanFactoryInitialization(beanFactory);方法,这个方法是理解IOC和AOP的核心方法。

finishBeanFactoryInitialization(beanFactory)方法简要概述

  • 构造器注解信息收集
  • bean的实例化过程
  • 字段和方法注解信息收集
  • IOC的DI依赖注入的支持
  • 实例化后置处理方法执行
  • AOP的功能支持

可见finishBeanFactoryInitialization方法是Spring中一个非常核心的一个方法。

2.图解Bean实例化流程

Spring中Bean的实例化过程_第1张图片

上述流程图是一个Bean实例化的时序图,当然是简要一点的,并没有把特别详细的内容也绘制上去。Spring的Bean实例化过程比较复杂,它需要考虑很多问题,比如构造函数选用,循环引用问题,后置初始化问题,AOP问题等。

在我的流程图中,有BeanPostProcessor后缀的类,承担了一些功能性的任务,而且被多次调用到了,那么BeanPostProcessor它到底是一个什么东西?

3.论BeanPostProcessor

什么是BeanPostProcessor?

BeanPostProcessor在Bean的实例化过程中最重要的接口,也是Spring的一个巧妙的设计。

			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					Constructor[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
					if (ctors != null) {
						return ctors;
					}
				}
			}

上述代码描述了在Spring中有一个BeanPostProcessors集合,通过getBeanPostProcessors()方法获取到这个集合,然后遍历。判断是实现了SmartInstantiationAwareBeanPostProcessor接口的对象就去执行determineCandidateConstructors这个方法得到期望的返回值。

那么如我我们也想在这个阶段做一些操作怎么办?

我们可以继承SmartInstantiationAwareBeanPostProcessor,实现determineCandidateConstructors这个方法,然后使用注解@Component把这个类交给Spring来管理。当Spring容器初始化执行到这个位置的时候,是可以遍历到我们自定义的BeanPostProcessor实现类的。

BeanPostProcessor在实例化过程中是一个什么样的角色?

在Spring中有很多种类的BeanPostProcessor,如AutowireAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、AbstractAutoProxyCreator等,它们最终都直接或间接的实现了BeanPostProcessor接口,那么这些实现类在Bean的实例化过程中承担了哪些工作呢?

  1. AutowireAnnotationBeanPostProcessor:
    获取有@Autowire注解的构造函数,方法,字段。
    找到对象中@Autowire注解信息去反射调用方法或字段赋值。

  2. CommonAnnotationBeanPostProcessor:
    @Resource注解字段信息获取。
    @PostConstruct和@PreDestory注解方法信息获取。
    反射调用@PostConstruct方法,@Resource属性赋值。

  3. AbstractAutoProxyCreator:
    判断实例化的Bean是否需要被代理,如果该Bean是有切面的,也就是该类在切入点上,那么就需要增强对应的方法,创建代理对象。

综上所述,在Spring的Bean的实例化流程中,这个BeanPostProcessor起到了至关重要的作用。

4.源码解析Bean的实例化过程

在源码解析过程中会跳过特殊情况的代码,有一些方法中代码直接会以省略号进行省略,细节的内容会延伸出比较多的业务,文章会显得很不流畅,我们看到的源码是通过DEBUG快速的跟踪默认的流程。

4.1 找到入口代码

DefaultListableBeanFactory -> preInstantiateSingletons()方法

	@Override
	public void preInstantiateSingletons() throws BeansException {
		/**
		 * beanDefinitionNames是存beanNames的容器,还有一个Map。
		 * beanName -> beanDefinition Map映射
		 * alias -> beanName的映射
		 * beanDefinitionNames就是存全部的beanName
		 */
		List beanNames = new ArrayList<>(this.beanDefinitionNames);
		/**
		 * 循环实例化 beanNames , 所有bean的名称都遍历一遍符合条件的就实例化
		 */
		for (String beanName : beanNames) {
			/**
			 * 父子标签的内容合并MergedLocalBeanDefinition的获取
			 *
			 * 没有父标签就返回一个常规的RootBeanDefinition
			 */
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			/**
			 * 非抽象的、是单例的、非懒加载的 才会去实例化
			 */
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				/**
				 * 判断是否实现了FactoryBean接口
				 */
				if (isFactoryBean(beanName)) {
					// ... ... 省略
				}
				else {
					/**
					 * 未实现FactoryBean接口的实现类 可以创建一个非当前bean的对象,放入一个特定的集合中去。
					 *
					 * 实例化核心方法 * * * * *
					 */
					getBean(beanName);
				}
			}
		}

		// ... ... 省略
	}

上述代码,首先是遍历之前我们提到过的beanDefinitionNames集合,因为该集合存放着我们管理的全部的BeanName,通过BeanName去调用getMergedLocalBeanDefinition(beanName);得到BeanDefinition,为什么方法名叫MergedLocalBeanDefinition,它不仅仅是将该beanDefinition取出来,更是看该BeanDefinition是否有parent父标签,完成合并工作,最后依然是BeanDefinition。

得到了BeanDefinition后会进行判断,该Bean是否是单例的,非懒加载的,非抽象的,符合全部条件才会进行创建。

然后会判断Class是否实现了FactoryBean接口,这个FactoryBean接口有一个GetBean方法,Spring容器初始化后,我们要想获得这个Class的bean通过beanName去获取是不行的,只能获取到getBean这个方法的返回的对象,而不是Class的对象。想要获得Class的对象需要在Beanname前加&符号。(不过多描述,自己百度小案例尝试下就行了)

如果没有实现FactoryBean接口,就会调用getBean(beanName);方法获取对象。

4.2 不断的getBean直到doGetBean

AbstractBeanFactory -> doGetBean

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

		/**
		 * 通过name拿到Bean的名称,有可能这个name是别名。
		 */
		final String beanName = transformedBeanName(name);
		Object bean;

		/**
		 * 如果能从一级缓存中拿到实例,singtonObjects
		 */
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		} else {
			/**
			 *  singletonObjects一级缓存中没有实例
			 *  判断是否有循环依赖,单例singleton可以循环依赖,但是Prototype不可以循环依赖,一旦发现就会报错。
			 *
			 *  这里是检测 beanName 在正在创建多例的实例集合中,就会抛出异常。
			 */
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}
			// ... ... 省略
			try {
				/**
				 * 父子合并
				 *
				 * 检验bean是否是抽象的
				 */
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				/**
				 * dependsOn属性,这个Bean初始化依赖的对象,会在这个Bean初始化之前创建。
				 */
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						// ... ... 省略
						registerDependentBean(dep, beanName);
						try {
							/**
							 * 实例化 递归调 -> doGetBean
							 */
							getBean(dep);
						} catch (NoSuchBeanDefinitionException ex) {
							// ... ... 省略
						}
					}
				}
				/**
				 * 重要:着重看
				 * Bean默认都是单例的
				 */
				if (mbd.isSingleton()) {
					/**
					 * 1。方法体内容执行 容器记录当前正在创建的bean
					 * 2。lambda表达式,先执行getSingleton中的内容,然后在getSingleton中执行lambda表达式的方法体。
					 * 3。加入到一级缓存并删除二三级缓存
					 */
					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;
						}
					});
					/**
					 * 实例化 IOC做完了 才调到 getObjectForBeanInstance
					 *
					 * demo12
					 * 该方法是对FactoryBean的一个支持。完成FactoryBean接口的调用
					 */
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				} else if (mbd.isPrototype()) {
					/**
					 * 如果是一个原型类型的,并非是单例的。
					 * 在拿到beanDefinition后,就创建一个新的对象
					 * 每次getbean获取到的对象都是新的。
					 */
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						/**
						 * 集合存放正在创建的原型beanName
						 */
						beforePrototypeCreation(beanName);
						/**
						 * demo 13
						 * 创建实例
						 */
						prototypeInstance = createBean(beanName, mbd, args);
					} finally {
						/**
						 * 集合移除正在创建的原型beanName
						 */
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				} else {
					// ... ... 省略
				}
			// ... ... 省略
		return (T) bean;
	}

代码流程描述

  1. 首先是从缓存中获取实例,一级拿不到拿二级,二级拿不到拿三级。
  2. 判断是否有循环依赖,单例之间可以循环依赖,但是原型模式的两种Bean之间不可以循环以来,不然就会报错。(这是一个关键点会单独整理)
  3. 父子BeanDefinition的合并
  4. dependsOn属性,如果有这个Bean初始化依赖的对象需要先行getBean进行创建。
  5. bean是单例的就调用getSingleton方法,getSingleton(String beanName, ObjectFactory singletonFactory) ,其中singletonFactory是上述代码中的lambda表达式方法体。getSingleton方法中,记录正在创建的bean,执行lambda方法体,得到对象后删除23级缓存加入一级缓存。
  6. 完成对factoryBean接口的调用。
  7. 如果是原型模式,创建单独的bean,每次都创建新的Bean。

上述内容中最为关键的就是第5步的lambda,方法体中return createBean(beanName, mbd, args);,调用了createBean方法进行实例化。

4.3 不断的createBean最后doCreateBean

AbstractAutowireCapableBeanFactory -> doCreateBean

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

		/**
		 * BeanWrapper 封装的是bean的实例,包含编辑器和类型转换器
		 */
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			/**
			 * 【创建实例的过程】
			 *
			 * 1.factorybean
			 * 2.有参数构造函数初始化
			 * 3.无参数构造函数初始化
			 *
			 * 重要: * * * * *
			 */
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					/**
					 * CommonAnnotationBeanPostProcessor  支持@BeanPostConstruct @PreDestory @Resource
					 * AutowiredAnnotationBeanPostProcessor 支持@Autowire注解和@Value注解
					 * BeanPostProcessor接口的典型应用
					 *
					 * 【注解信息收集】对类中注解对装配过程,依赖注入对装配收集
					 *
					 * 重要程度:* * * * *
					 */
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				// ... ... 省略
				mbd.postProcessed = true;
			}
		}

		/**
		 * 是否是单例bean 暴露出来
		 */
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			}
			/**
			 * 放入三级缓存,涉及到循环依赖的知识点
			 *
			 * beanName 和 创建好的实例 但是没有初始化属性 简直对装入三级缓存的Map中
			 *
			 * 重要 * * * * *
			 */
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		Object exposedObject = bean;
		try {

			/**
			 * ioc DI 的过程
			 * demo10
			 * 扫描注解信息,Autowired Resource PostConstrcut PreDestory等。
			 * 反射注入对象给属性或方法参数。
			 *
			 * 重要 * * * * *
			 */
			populateBean(beanName, mbd, instanceWrapper);

			/**
			 * Bean实例化且DI后执行一些业务初始化逻辑
			 *
			 *
			 * demo16
			 * 配置的初始化方法调用
			 *
			 * init-method
			 * InitializingBean接口afterPropertiesSet方法
			 * @PostConstruct注解下的方法
			 *
			 * 包含AOP入口
			 *
			 * 重要 * * * * *
			 */
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		// ... ... 省略
		try {
			/**
			 * Bean的销毁
			 *
			 * 注册bean销毁时的类 DisposableBeanAdapter
			 * 注册一个销毁的方式
			 */
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		// ... ... 省略
		return exposedObject;
	}

代码流程描述

  1. createBeanInstance(beanName, mbd, args)有参构造函数的获取,反射创建实例。
  2. 收集@BeanPostConstruct @PreDestory @Resource @Autowire注解和@Value注解信息。
  3. 是单例的Bean率先暴露到三级缓存中。
  4. 依赖注入 populateBean(beanName, mbd, instanceWrapper) , 反射注入属性/调用方法。
  5. 后置初始化处理和AOP判断。 initializeBean(beanName, exposedObject, mbd);
  6. 当前bean注册一个销毁的类DisposableBeanAdapter,registerDisposableBeanIfNecessary(beanName, bean, mbd);
  7. 返回Bean

上述就是Bean实例化的全部流程,1 - 6会依次的进行一个详细的总结。

4.4 有参和无参构造函数的初始化

AbstractAutowireCapableBeanFactory -> createBeanInstance

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		/**
		 * 拿到BeanName对应的class对象
		 */
		Class beanClass = resolveBeanClass(mbd, beanName);

		// ... ... 省略

		/**
		 * FactoryMethod的名称不为空,希望通过某个方法创建 beanWapper
		 *
		 * 完成BeanDefinition中BeanFactroy属性方法的调用
		 *
		 * @Bean的注解是factory-method属性来实现的
		 *
		 * 配置bean的factory-method属性的类需要反射调用mbd的工厂方法获取bean
		 */
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// ... ... 省略

		/**
		 * 构造函数的实例化,非 FactoryMethod 实例化很少用。   demo 10
		 *
		 * 通过一个beanPostProcessor完成构造器的返回
		 *
		 * 寻找当前实例化的bean中构造器是否有@Autowire注解
		 *
		 * 构造函数实例化:有参数
		 *
		 * 重要程度:* * * * *
		 */
		// 拿到构造器的数组,构造器可能会重载。 可以看下
 		Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {

			/**
			 * 如果ctors不为空,就说明构造函数上有@Autowire注解
			 * 反射创建对象
			 */
			return autowireConstructor(beanName, mbd, ctors, args);
		}
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		/**
		 * 最后非上述情况,使用无参数构造器实例化
		 */
		return instantiateBean(beanName, mbd);
	}

代码流程描述

  1. 获取BeanName对应的class对象。
  2. 标签中配置的factory-method不为空就用这个方法来创建bean/
  3. AutowiredAnnotationBeanPostProcessor获取@Autowire注解的构造函数, 如果有有参构造函数就用有参构造。
  4. 如果获取构造器为空,使用无参构造函数进行初始化。

有参构造实例化最终代码
BeanUtils -> instantiateClass

			/**
			 * newInstance实例化
			 */
			return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
					KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));

获取有参构造器BeanPostProcessor调用
AbstractAutowireCapableBeanFactory -> determineConstructorsFromBeanPostProcessors

	protected Constructor[] determineConstructorsFromBeanPostProcessors(@Nullable Class beanClass, String beanName)
			throws BeansException {

		/**
		 * 装配beanPostProcessor的时候会判断其类型并设置 hasInstantiationAwareBeanPostProcessors 属性
		 * 符合条件才去找构造函数
		 */
		if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
			/**
			 * getBeanPostProcessors拿到beanFactory中的所有BeanPostProcessor接口
			 *
			 *		spring-context  component-scan注解解析中  注册了AutowiredAnnotationBeanPostProcessor。
			 * 		beanPostProcessor在流程中都会注册到beanFactory中
			 * 遍历列表
			 * 		找到一个合格的构造函数
			 */
			for (BeanPostProcessor bp : getBeanPostProcessors()) {

				/**
				 * 埋在bean实例化流程中的一个点,遍历每个SmartInstantiationAwareBeanPostProcessor类型的beanPostProcessor。
				 *
				 * 使得每个beanPostProcessor去执行自己关注的内容。
				 */
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {

					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;

					/**
					 * 获取有autowire注解的构造函数 找到合格的构造函数
					 */
					Constructor[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);

					if (ctors != null) {
						return ctors;
					}
				}
			}
		}
		return null;
	}

代码描述AutowiredAnnotationBeanPostProcessor继承了SmartInstantiationAwareBeanPostProcessor。此处执行的是AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors方法。

4.5 类注解信息收集

AbstractAutowireCapableBeanFactory -> applyMergedBeanDefinitionPostProcessors

	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class beanType, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				/**
				 * CommonAnnotationBeanPostProcessor
				 * AutowiredAnnotationBeanPostProcessor
				 */
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}

AutowiredAnnotationBeanPostProcessor继承了MergedBeanDefinitionPostProcessor
CommonAnnotationBeanPostProcessor继承了MergedBeanDefinitionPostProcessor

所以此处执行的是AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor的postProcessMergedBeanDefinition方法。

CommonAnnotationBeanPostProcessor 支持收集 @BeanPostConstruct @PreDestory @Resource注解信息
AutowiredAnnotationBeanPostProcessor 支持收集 @Autowire注解和@Value注解信息
AutowiredAnnotationBeanPostProcessor的postProcessMergedBeanDefinition

	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
		/**
		 * 找到@Autowired注解的属性或方法
		 */
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		/**
		 * beanDefinition信息维护 externallyManagedConfigMembers
		 */
		metadata.checkConfigMembers(beanDefinition);
	}

CommonAnnotationBeanPostProcessor的postProcessMergedBeanDefinition

	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
		/**
		 * 扫描 @PostConstruct @PreDestory
		 */
		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
		/**
		 * 获取 @Resource 元数据信息
		 */
		InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
		/**
		 * 设置beanDefinition中的
		 * externallyManagedConfigMembers
		 * 属性
		 */
		metadata.checkConfigMembers(beanDefinition);
	}

父类的postProcessMergedBeanDefinition被调用到了

	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
		/**
		 * 扫描类方法注解并包装对象
		 */
		LifecycleMetadata metadata = findLifecycleMetadata(beanType);
		/**
		 * 设置beanDefinition中的
		 * externallyManagedDestroyMethods
		 * externallyManagedInitMethods
		 * 属性
		 */
		metadata.checkConfigMembers(beanDefinition);
	}

4.6 单例Bean提前暴露到三级缓存

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

单例的Bean涉及到循环引用的问题,在构造器实例化 A 之后,DI依赖注入时 A 引用了 B,此时需要getBean(B) 来注入到 A中,getBean实例化 B 的过程中,B 引用了 A,就要再次getBean A,但是此时A正在创建,如果不在DI依赖注入前暴露实例到缓存,程序就会陷入死循环。
每次getBean先查一二三级缓存,就是为了解决循环依赖的问题。

getEarlyBeanReference(beanName, mbd, bean)就是返回的当前实例化好的对象的引用。

这里涉及到了BeanPostProcessor的调用,直接返回的当前引用,没什么逻辑。

4.7 DI依赖注入

AbstractAutowireCapableBeanFactory -> populateBean

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		// ... ... 省略

		/**
		 * DI重点代码块
		 */
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			// 循环BeanPostProcessor
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					/**
					 * 高版本依赖注入过程 @Autowired注解支持
					 *
					 * AutowiredAnnotationBeanPostProcessor
					 *
					 * 重点代码:* * * * *
					 */
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						/**
						 * 老版本依赖注入过程 @Autowired注解支持
						 */
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}
		// ... ... 省略

		/**
		 * 基于XML配置的方式去进行依赖注入
		 *
		 * 父子标签依赖,其中父标签的属性就是在这里通过反射设置到子标签对象的属性中的。
		 *
		 * 标签做依赖注入 ref="" 很不常用了,比较复杂
 		 */
		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

依赖注入的过程是在AutowiredAnnotationBeanPostProcessor完成的。
AutowiredAnnotationBeanPostProcessor -> postProcessProperties

	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
		/**
		 * Autowired注入方法
		 * 之前曾把metadata提取到并放入缓存中
		 */
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
			metadata.inject(bean, beanName, pvs);
		} catch (BeanCreationException ex) {
			throw ex;
		} catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
		}
		return pvs;
	}

主要看metadata.inject(bean, beanName, pvs);注入过程。
InjectionMetadata -> inject

	public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
		Collection checkedElements = this.checkedElements;
		Collection elementsToIterate =
				(checkedElements != null ? checkedElements : this.injectedElements);
		if (!elementsToIterate.isEmpty()) {
			for (InjectedElement element : elementsToIterate) {
				if (logger.isTraceEnabled()) {
					logger.trace("Processing injected element of bean '" + beanName + "': " + element);
				}
				/**
				 * bean注入内容
				 */
				element.inject(target, beanName, pvs);
			}
		}
	}

调用到另一个重载的函数
element.inject(target, beanName, pvs);
InjectionMetadata -> inject

		protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
				throws Throwable {

			/**
			 * 是属性
			 */
			if (this.isField) {
				Field field = (Field) this.member;
				ReflectionUtils.makeAccessible(field);
				field.set(target, getResourceToInject(target, requestingBeanName));
			}
			/**
			 * 是方法
			 */
			else {
				if (checkPropertySkipping(pvs)) {
					return;
				}
				try {
					Method method = (Method) this.member;
					ReflectionUtils.makeAccessible(method);
					method.invoke(target, getResourceToInject(target, requestingBeanName));
				}
				catch (InvocationTargetException ex) {
					throw ex.getTargetException();
				}
			}
		}

一目了然,是属性就注入进去,是方法就去执行。

4.8 后置初始化和AOP代理

AbstractAutowireCapableBeanFactory -> initializeBean

	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		/**
		 * 如果bean实现过下列的Aware接口,方法都是在这里触发的。
		 * BeanNameAware
		 * BeanClassLoaderAware
		 * BeanFactoryAware
		 */
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}


		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			/**
			 * 某些特殊方法的调用 @PostConstruct,Awire接口
			 * 重要程度:* * * * *
			 */
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			/**
			 * InitializingBean接口
			 * 	afterPropertiesSet方法和init-method属性调用
			 * 重要程度:* * * * *
			 */
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}

		/**
		 *  Aop入口,有切面的实例才会被代理。
		 */
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
 
  

代码描述

  1. 一些Aware接口的执行
  2. @PostConstruct方法执行
  3. InitializingBean接口方法和init-method属性方法执行
  4. Aop入口,有切面的实例才会被代理

其中2和4是基于BeanPostProcessor去实现的。Aop比较复杂,后续会单独整理总结。

这部分代码不难,就不一一粘贴了。

三、总结

bean的实例化流程内容比较多,有一些概念还是需要有一定的底子才能理解的,需要承上启下,如果有一些内容不太理解可以看看我之前写的一些spring文章。对于本篇总结中有一些地方没有贴到代码的地方,我这边整体详细的看过多遍都有注释,欢迎提问和讨论。

你可能感兴趣的:(Spring,java,spring,ioc,aop)