Spring生命周期(下)
在上篇文章中,我们已经对Bean的生命周期做了简单的介绍,主要介绍了整个生命周期中的初始化阶段以及基于容器启动停止时LifecycleBean的回调机制,另外对于Bean的销毁过程做了简单的介绍,但是对于整个Bean的生命周期,这还只是一小部分,在这篇文章中,我们将学习完剩下部分的学习,同时对之前内容做一次复习,整个Bean的生命周期,按照我们之前的介绍,可以分为四部分
实例化
属性注入
初始化
销毁
本文介绍实例化及属性注入阶段
生命周期概念补充
虽然我们一直说整个Bean的生命周期分为四个部分,但是很多同学一直对Bean的生命周期到底从哪里开始,到哪里结束没有一个清楚的概念。可能你会说,不就是从实例化开始,到销毁结束吗?当然,这并没有错,但是具体什么时候开始实例化呢?什么时候又算销毁呢?这个问题能否清楚的回答呢?如果不能请继续往下看。
笔者认为,整个Spring的生命周期,从第一次调用 applyBeanPostProcessorsBeforeInstantiation方法开始的,这个方法见名知意,翻译过来就是在实例化之前调用后置处理器,applyBeanPostProcessorsAfterInitialization 这个方法的调用,意味着Bean的生命周期中创建阶段的结束。对于销毁没有任何歧义,就是调用Bean的销毁方法意味着这个Bean走到了生命尽头,标志着Bean生命周期的结束,那么结合上篇文章的结论,我们把Bean的生命周期的范围定一下:
需要注意的是,对于BeanDefinition的扫描,解析,验证并不属于Bean的生命周期的一部分。这样清晰的界定Bean的生命周期的概念是很有必要的,也许刚刚开始对于我们而言,Bean的生命周期就是一团乱麻,但是现在至少我们抓住了线头。而整个Bean的生命周期,我们分为两部分
创建
销毁
对于销毁阶段,我们不需要过多的关注,对于创建阶段,开始的标志行为为:applyBeanPostProcessorsBeforeInstantiation 方法执行,结束的标志行为为:
applyBeanPostProcessorsAfterInitialization 方法执行
基于上面的结论,我们接下来对代码进行分析:
实例化
整个实例化的过程主要的代码在createBean()方法和doCreateBean()方法
createBean流程分析
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
//第一步,解析BeanDefinition中的Beanclass属性
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
//第二步
// 对通过XML定义的bean中的look-up方法进行预处理
// 对于@Lookup注解标注的方法不在这里进行处理,@AutowiredAnnotationBeanPostProcessor会处理@Lookup注解
// 不研究了
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 1、实例化前 null 判断这个类在之后是否需要进行AOP代理
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 Spring自带的创建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);
}
}
第一步第二步只是对BeanDefinition中的一些属性做处理,它并不是Bean的生命周期的一部分,我们直接跳过看第三步
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// beforeInstantiationResolved为null或true
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
//不是合成类,并且有实例化后置处理器,这个判断基本成立
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//获取BeanDefinition的类型
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 实例化前
//这里执行的主要是AbstractAutoProxyCreator这个类中的方法,决定是否需要AOP代理
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
//这里执行了一个短路操作如果在这个后置处理器返回了一个Bean,那么后面的相关操作不会执行了,只会执行一个aop的操作
if (bean != null) {
//虽然这个bean被短路了意味着不需要经过后面的初始化,但是如果需要代理的话,还是要进行AOP
//这个地方的短路操作意味着我们直接在后置处理器中提供了一个充分的Bean,这个Bean不需要进行初始化,但需不需要进行代理
//仍然有AbstractAutoProxyCreator的applyBeanPostProcessorsBeforeInstantiation这个方法决定这个地方还是要调用一次Bean的
//初始化后置处理器保证Bean被完全处理完
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
//beforeInstantiationResolved基本上会返回false
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
对于 AbstractAutoProxyCreator 中的applyBeanPostProcessorsBeforeInstantiation这个方法的分析我们暂且不管,等到Aop学习阶段在进行详细分析,我们暂且只需要知道这个方法会决定在后续中要不要为这个Bean产生代理对象。
doCreateBean 流程分析
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//第一步:单例情况下,看factoryBeanInstanceCache这个缓存中是否有
// factoryBeanObjectCache:存的是beanName对应的FactoryBean.getObject()所返回的对象
// factoryBeanInstanceCache:存的是beanName对应的FactoryBean实例对象
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 2、实例化
if (instanceWrapper == null) {
//第二步、 创建bean实例 new USerSerive()
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 原始对象
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//第三步、 运行修改合并好了的BeanDefinition
// 这里会查找@Autowired的注入点(InjectedElement),并把这些注入点添加到mbd的属性externallyManagedConfigMembers中
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 如果当前创建的是单例bean,并且允许循环依赖,并且还在创建过程中,那么则提早暴露
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//第四步、提前暴露一个工厂对象
// 此时的bean还没有完成属性注入,是一个非常简单的对象
// 构造一个对象工厂添加到singletonFactories中
// 第四次调用后置处理器
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); // AService
}
// Initialize the bean instance.
// 对象已经暴露出去了
Object exposedObject = bean;
try {
//第五步、属性注入
// 3、填充属性 @Autowired
populateBean(beanName, mbd, instanceWrapper); //
//第六步 初始化
// 4、 初始化 和 BeanPostProcessor 正常AOP BeanPostProcessor
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
// 在解决循环依赖时,当AService的属性注入完了之后,从getSingleton中得到AService AOP之后的代理对象
Object earlySingletonReference = getSingleton(beanName, false); // earlySingletonObjects
if (earlySingletonReference != null) {
// 如果提前暴露的对象和经过了完整的生命周期后的对象相等,则把代理对象赋值给exposedObject
// 最终会添加到singletonObjects中去
if (exposedObject == bean) { //
exposedObject = earlySingletonReference;
}
// 如果提前暴露的对象和经过了完整的生命周期后的对象不相等
// allowRawInjectionDespiteWrapping表示在循环依赖时,只能
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
// AService的原始对象被注入给了其他bean,但是AService最后被包装了
// 也就是说其他bean没有用到AService的最终版本
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
//第七步、注入需要销毁的Bean,放到一个销毁的map中(disposableBeans)
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
第一步:factoryBeanObjectCache 什么时候不为空?
if (mbd.isSingleton()) {
//第一步:单例情况下,看factoryBeanInstanceCache这个缓存中是否有
// factoryBeanObjectCache:存的是beanName对应的FactoryBean.getObject()所返回的对象
// factoryBeanInstanceCache:存的是beanName对应的FactoryBean实例对象
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
这段代码深究起来很复杂的,我这里单纯理论解释下:
假设我们现在有一个AService,它有一个属性B,代码如下:
@Component
public class AService {
@Autowired
B b;
public B getB(){
return b;
}
}
@Component
public class B {
}
而这个B又是采用FactoryBean的形式配置的,如下
@Component
public class TestFactoryBean implements SmartFactoryBean {
@Override
public Object getObject() throws Exception {
return new B();
}
@Override
public Class<?> getObjectType() {
return B.class;
}
//这个地方并不一定配置成懒加载,这里只是为了让TestFactoryBean在AService之后实例化
@Override
public boolean isEagerInit() {
return false;
}
}
我们思考一个问题,在上面的场景下,当AService要完成属性注入时,Spring会怎么做呢?
Spring现在知道AService要注入一个类型为B的属性,所以它会遍历所有解析出来的BeanDefinition,然后每一个BeanDefinition中的类型是不是B类型。类似下面这样:
for (String beanName : this.beanDefinitionNames) {
//1、获取beanDefinition
//2、根据BeanDefinition中的定义判断是否是一个B
}
上面这种判断大部分情况下是成立的,但是对于一种特殊的Bean是不行的。就是我们之前介绍的FactoryBean,因为我们配置的FactoryBean的目的并不是使用其本身,而是想要通过它的getObject方法将一个对象放到Spring容器中,所以当我们遍历到一个BeanDefiniton,是一个Factory时就要做特殊处理,我们知道FactoryBean中有一个getObjectType方法,通过这个方法我们可以得到要被这个Factory创建的对象的类型,如果我们能调用这个方法的话,那么我们就可以来判断这个类型是不是B
但是在上面的例子中 ,这个TestFactoryBean还没有创建出来,所以Spring在这个时候会去实例化这个TestFactoryBean,然后调用其getObjectType方法,再做类型判断,最后进行属性注入,伪代码如下:
for (String beanName : this.beanDefinitionNames) {
//1、获取BeanDefinition
//2、如果不是一个FactoryBean,直接根据BeanDefinition中的属性判断
if (不是一个FactoryBean) {
//直接根绝BeanDefinition属性判断是不是B
}
//3、如果是一个FactoryBean
if (是一个FactoryBena) {
//先创建FactoryBean,然后再调用getObjectType方法了
}
}
大家可以自己自己调试
第二步:创建对象(createBeanInstance)
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 创建一个bean实例(返回一个原始对象)
// Make sure bean class is actually resolved at this point.
// 1. 得到bean的class,并验证class的访问权限是不是public
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 2. 这是Spring提供给开发者的扩展点
// 如果我们要自己来实现创建对象的过程, 那么就可以提供一个Supplier的实现类,
// 当一个BeanDefinition中存在一个Supplier实现类的时候, Spring就利用这个类的get方法来获取实例,
// 而不再走Spring创建对象的逻辑
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 3.通过factoryMethod实例化这个bean
// factorMethod这个名称在xml中还是比较常见的, 即通过工厂方法来创建bean对象
// 如果一个bean对象是由@Bean注解创建的, 那么该对象就会走instantiateUsingFactoryMethod方法来创建的
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
// 如果在创建bean时没有手动指定构造方法的参数,那么则看当前BeanDefinition是不是已经确定了要使用的构造方法和构造方法参数
// 注意:如果没有手动指定参数,那么就肯定时自动推断出来的,所以一旦发现当前BeanDefinition中已经确定了要使用的构造方法和构造方法参数,
// 那么就要使用autowireConstructor()方法来构造一个bean对象
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// 该BeanDefinition是否已经决定了要使用的构造方法或工厂方法
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
// 该BeanDefinition是否已经决定了要使用的构造方法参数
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
// resolved为true,表示当前bean的构造方法已经确定出来了
// autowireNecessary表示
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 如果构造方法已经确定了,但是没有确定构造方法参数,那就表示没有构造方法参数,用无参的构造方法来实例化bean
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
//跟后置处理器相关,我们主要关注这行代码 推断构造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 通过BeanPostProcessor找出了构造方法
// 或者BeanDefinition的autowire属性为AUTOWIRE_CONSTRUCTOR
// 或者BeanDefinition中指定了构造方法参数值
// 或者在getBean()时指定了args
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 进行构造方法推断并实例化
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
// 没啥用
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// 用无参的构造方法来实例化bean
return instantiateBean(beanName, mbd);
}
在这里其余的代码不做过多的关注,我们暂且知道在创建对象的过程中,Spring会调用一个后置处理器来推断构造函数。
第三步:applyMergedBeanDefinitionPostProcessors
修改合并好的Beandefinition,这里会查找@Autowired的注入点(InjectedElement),并把这些注入点添加到mbd的属性externallyManagedConfigMembers中
我们就以AutowiredAnnotationBeanPostProcessor这个类来看一下大概作用
// 寻找注入点
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 获取beanType中的注入点
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
第四步、getEarlyBeanReference
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) { // AOP
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
//在这里保证注入的对象是一个代理对象(如果需要代理的话),主要用于循环依赖
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
属性注入
第五步、属性注入(populateBean)
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
// 可以提供InstantiationAwareBeanPostProcessor,控制对象的属性注入
// 我们可以自己写一个InstantiationAwareBeanPostProcessor,然后重写postProcessAfterInstantiation方法返回false,那么则不会进行属性填充了
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
// 是否在BeanDefinition中设置了属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// autowire属性
int resolvedAutowireMode = mbd.getResolvedAutowireMode(); // BeanDefinition AutowireMode
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// by_name是根据根据属性名字找bean
// by_type是根据属性所对应的set方法的参数类型找bean
// 找到bean之后都要调用set方法进行注入
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
// 总结一下
// 其实就是Spring自动的根据某个类中的set方法来找bean,byName就是根据某个set方法所对应的属性名去找bean
// byType,就是根据某个set方法的参数类型去找bean
// 注意,执行完这里的代码之后,这是把属性以及找到的值存在了pvs里面,并没有完成反射赋值
}
// 执行完了Spring的自动注入之后,就开始解析@Autowired,这里叫做实例化回调
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
// @AUtowired注解的 AutowiredAnnotationBeanPostProcessor
// @Resource注解的 CommonAnnotationBeanPostProcessor
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 调用BeanPostProcessor分别解析@Autowired、@Resource、@Value,得到属性值
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
// pvs存的就是属性已经对应的值
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
// pvs存的就是属性已经对应的值
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
在上面的流程中,主要关注一个方法 postProcessProperties,这个方法会将之前通过postProcessMergedBeanDefinition方法找到注入点,在这一步进行注入。完成属性注入后就开始初始化了。初始化在上篇已经讲了,就不再赘述了。