2.spring源码之bean实例化及初始化流程

前一篇文章讲解了beanFactory的初始化流程,这篇文章我们接着往下分析spring bean的实例化及初始化流程

入口点:

        ClassPathXmlApplicationContext cs=new ClassPathXmlApplicationContext("xxx");
        cs.getBean("bean1");
        
    public Object getBean(String name) throws BeansException {
        return this.doGetBean(name, (Class)null, (Object[])null, false);
    }

0.流程图总结

1.bean整体流程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uFr2TvXI-1604735670437)(D:\Typora\java核心\A源码专题\spring\assets\1603886668995.png)]

2.加载流程

在这里插入图片描述

3.实列化流程

在这里插入图片描述

在这里插入图片描述

4.初始化流程

在这里插入图片描述

1.bean初始化流程:

在这里插入图片描述

(1)转换对应的beanName
这里传入的参数name并不一定是beanName,可能是别名,也可能是FactoryBean,所以进行一系列的解析,这些解析内容如下
1)去除FactoryBean的修饰符,也就是name="&aa",那么首先会去除&,而使name=aa
2)取指定别名所表示的最终的beanName

(2)尝试从缓存中加载单例
单例在spring的同一个容器内只会被创建一次,后续在获取bean,就直接从单例缓存中获取了,当然,这里也只是尝试加载,
首先尝试从缓存中加载,如果加载不成功则再次尝试从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况
而在创建依赖的时候为了避免循环依赖,在spring中创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入
到缓存中,一旦下一个bean创建的时候需要依赖上一个bean则直接使用ObjectFactory

(3)bean的实例化
如果缓存中得到了bean的原始状态,则需要对bean进行实例化,缓存中的记录只是最原始的bean状态,并不一定是我们最终想要的bean,
举个例子,假如我们想对工厂bean进行处理,那么这里得到的是工厂bean的初始状态,但是我们真正想要的是工厂bean定义的factory-method
方法中返回的bean,而getObjectForBeanInstance就是完成这个工作的

(4)原型模式的依赖检查
只有在单例情况下才会尝试解决循环依赖,如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还没创建完成的时候,因为
对B的创建再次返回创建A,造成循环依赖,也就是(isPrototypeCurrentlyInCreation(beanName))为true的情况

(5)检测parentBeanFactory
从代码上看,如果缓存没有数据的话,直接转到父类工厂上去加载了,这是为什么?可能我们忽略了
parentBeanFactory != null && !containsBeanDefinition(beanName)这里面判断条件,parentBeanFactory != null,parentBeanFactory如果为空,
其他一切都是浮云,但是还有一个条件,!containsBeanDefinition(beanName),它是在检测如果当前加载的XML配置文件中,不包含beanName多对应的
配置,只能去parentBeanFactory中尝试,然后再去递归的调用递归方法

(6)将存储XML配置文件GenericBeanDefinition转换为RootBeanDefinition
因为从XML配置文件中读取到的bean信息存储在GenericBeanDefinition中,但是所有的bean的后续处理都是针对于RootBeanDefinition,
所以这里需要进行一个转换,转换的同时,如果父类bean不为空的话,则会一并合并父类属性

(7)寻找依赖
因为bean的初始化过程很肯能用到某些属性,而某些属性可能是动态配置的,并且配置成依赖其他的bean,那么这个时候必须先加载依赖的bean,
spring的加载顺序中,在初始化一个bean的时候,首先会初始化这个bean所对应的依赖

(8)针对不同的scope进行bean的创建
spring根据不同的配置进行不同的初始化策略,默认的是singleton

(9)类型转换
程序到这里已经基本结束了,通常对该方法的调用参数requireType是为空的,但是可能会存在这样的情况,返回的bean其实是个String,但是
requireType却传入的是Integer类型,那么这时候本步骤就起作用了,他的功能是将返回的bean转换为requireType所指定的类型。

代码:

    protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
        String beanName = this.transformedBeanName(name);
        Object sharedInstance = this.getSingleton(beanName);
        Object bean;
        if (sharedInstance != null && args == null) {
            if (this.logger.isTraceEnabled()) {
                if (this.isSingletonCurrentlyInCreation(beanName)) {
                    this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
                } else {
                    this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }

            bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
        } else {
            if (this.isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            BeanFactory parentBeanFactory = this.getParentBeanFactory();
            if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
                String nameToLookup = this.originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
                }

                if (args != null) {
                    return parentBeanFactory.getBean(nameToLookup, args);
                }

                if (requiredType != null) {
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }

                return parentBeanFactory.getBean(nameToLookup);
            }

            if (!typeCheckOnly) {
                this.markBeanAsCreated(beanName);
            }

            try {
                RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
                this.checkMergedBeanDefinition(mbd, beanName, args);
                String[] dependsOn = mbd.getDependsOn();
                String[] var11;
                if (dependsOn != null) {
                    var11 = dependsOn;
                    int var12 = dependsOn.length;

                    for(int var13 = 0; var13 < var12; ++var13) {
                        String dep = var11[var13];
                        if (this.isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }

                        this.registerDependentBean(dep, beanName);

                        try {
                            this.getBean(dep);
                        } catch (NoSuchBeanDefinitionException var24) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
                        }
                    }
                }

                if (mbd.isSingleton()) {
                    sharedInstance = this.getSingleton(beanName, () -> {
                        try {
                            return this.createBean(beanName, mbd, args);
                        } catch (BeansException var5) {
                            this.destroySingleton(beanName);
                            throw var5;
                        }
                    });
                    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                } else if (mbd.isPrototype()) {
                    var11 = null;

                    Object prototypeInstance;
                    try {
                        this.beforePrototypeCreation(beanName);
                        prototypeInstance = this.createBean(beanName, mbd, args);
                    } finally {
                        this.afterPrototypeCreation(beanName);
                    }

                    bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                } else {
                    String scopeName = mbd.getScope();
                    Scope 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, () -> {
                            this.beforePrototypeCreation(beanName);

                            Object var4;
                            try {
                                var4 = this.createBean(beanName, mbd, args);
                            } finally {
                                this.afterPrototypeCreation(beanName);
                            }

                            return var4;
                        });
                        bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    } catch (IllegalStateException var23) {
                        throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23);
                    }
                }
            } catch (BeansException var26) {
                this.cleanupAfterBeanCreationFailure(beanName);
                throw var26;
            }
        }

        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                } else {
                    return convertedBean;
                }
            } catch (TypeMismatchException var25) {
                if (this.logger.isTraceEnabled()) {
                    this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
                }

                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        } else {
            return bean;
        }
    }

2.着一刨析

1.factoryBean的使用


一般情况下,spring通过反射机制,利用bean的class属性指定实现类来实例化bean。在某些情况下,实例化bean的过程比较复杂,按照传统的方式,
则需要在bean的配置中提供大量的配置信息,配置方式的灵活性是受限的,spring为此提供了一个org.springframework.beans.factory.FactoryBean
工厂类接口,用户可以实现该接口定制实例化bean的逻辑

FactoryBean接口对于spring来说,占有重要地位,spring自身就提供了70多个FactoryBean的实现,从spring 3.0开始,FactoryBean开始支持泛型
接口声明为:

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l3RigUj7-1604735670458)(D:\Typora\java核心\A源码专题\spring\assets\copycode.gif)]](javascript:void(0)😉

public interface FactoryBean<T> {
    T getObject() throws Exception;
    Class<?> getObjectType();
    default boolean isSingleton() {
        return true;
    }
}

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9mzhx4HK-1604735670458)(D:\Typora\java核心\A源码专题\spring\assets\copycode.gif)]](javascript:void(0)😉

接口中定义的三个方法:
1)T getObject():返回由FactoryBean创建的bean实例,如果isSignleton()返回的是true,则该实例会方放到spring容器中单实例缓存池中
2)default boolean isSingleton():判断创建bean的scope
3)Class<?> getObjectType():返回创建bean的类型

2.缓存中获取单列bean

单例在spring的同一容器中只会被创建一次,然后再获取bean直接从单例缓存中获取,当然,这里也只是尝试加载,首先尝试从缓存中加载,
然后再次尝试从singletonFactories中加载,因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,
spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建的时候依赖上个bean
则直接使用ObjectFactory
下面的额源码是在org.springframework.beans.factory.support包下DefaultSingletonBeanRegistry中

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tT6uHz9R-1604735670459)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603886920601.gif)]](javascript:void(0)😉

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 检查缓存中是否存在实例
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        // 如果为空,则锁定全局变量并进行处理
        synchronized (this.singletonObjects) {
            // 如果此bean正在加载则不处理
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                // ObjectFactory初始化策略存储在singletonFactories
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    // 调用预先设定好的getObject()方法
                    singletonObject = singletonFactory.getObject();
                    // 记录在缓存中earlySingletonObjects和singletonFactories互斥
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

[复制代码](javascript:void(0)😉

这个方法首先尝试从singletonObjects里面获取实例,如果获取不到,再从earlySingletonObjects中获取,如果还获取不到,尝试从
singletonFactories中获取beanName对应的ObjectFactory,然后调用这个ObjectFactory的getObject()来创建bean,并放到earlySingletonObjects中去,
并且从singletonFactories中remove掉ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测时候使用,这里有几个不同的map:

singletonObjects:用于保存BeanName和创建bean实例之间的关系,bean name -> bean instance
singletonFactories:用于保存BeanName和创建bean工厂之间的关系,bean name -> ObjectFactory
earlySingletonObjects:用于保存BeanName和创建bean实例之间的关系,与ingletonObjects不同的是,当一个单例bean被放到这里面后,那么当bean
还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环引用
registeredSingletons:用来保存所有当前已存在的bean

private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
private final Map<String, Object> earlySingletonObjects = new HashMap(16);
private final Set<String> registeredSingletons = new LinkedHashSet(256);

3.factoryBean类型的实列化

在doGetBean()方法中,getObjectForBeanInstance是个高频使用的方法,无论是从缓存中获取bean还是根据不同的scope策略加载bean,总之,得到bean的实例后,我们第一步要做的就是调用这个方法来检测一下正确性,其实就是用于检测当前bean是否是FactoryBean类型的bean,如果是,那么需要调用该
bean对应的FactoryBean实例中的getObject()作为返回值

无论是从缓存中获取到bean还是从不同的scope策略中加载的bean都是最原始的bean状态,并不一定是我们最终想要的bean,而getObjectForBeanInstance方法就是完成这个工作的,该方法内部最后调用了facotry.getBean()来返回我们希望的得到的bean

4.加载bean

在这里插入图片描述

之前我们讲解了从缓存中获取单例的过程,那么,如果缓存中不存在已经加载的单例bean,就需要从头开始bean的加载过程了,而spring中使用了
getSingleton()的重载方法实现bean的加载过程

sharedInstance = this.getSingleton(beanName, () -> {
    try {
        return this.createBean(beanName, mbd, args);
    } catch (BeansException var5) {
        this.destroySingleton(beanName);
        throw var5;
    }
});	


public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    // 全局变量需要同步
    synchronized (this.singletonObjects) {
        // 首先检查对应的bean是否已经加载过,因为singleton模式其实就是复用以创建的bean,所以这一步是必须的
        Object singletonObject = this.singletonObjects.get(beanName);
        // 如果为空才可以进行singleton的bean的初始化
        if (singletonObject == null) {
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<>();
            }
            try {
                // 初始化bean
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
                afterSingletonCreation(beanName);
            }
            if (newSingleton) {
                // 加入缓存中
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

[复制代码](javascript:void(0)😉

上述代码中其实使用了回调方法,使得程序可以在单例创建的前后做一些准备及处理操作,而真正的获取单例bean的方法其实并不是在此方法中实现,
其逻辑是在ObjectFactory类型的实例singletonFactory中实现的,而这些准备和处理操作包括如下:
(1)检查缓存中是否已经加载过
(2)若没有加载,则记录beanName的正在加载状态
(3)加载单例前记录加载状态

可能你会觉得beforeSingletonCreation方法是个空实现,里面没有任何逻辑,但其实不是,这个函数中做了一个很重要的操作:记录加载状态,也就是
通过this.singletonsCurrentlyInCreation.add(beanName)将当前正要创建的bean记录在缓存中,这样就可以对循环依赖进行检测 同一个类中

protected void beforeSingletonCreation(String beanName) {
     if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
     }
 }

(4)通过调用参数传入的ObjectFactory的个体Object方法实例化bean
(5)加载单例后的处理方法调用
同步骤3的记录加载状态相似,当bean加载结束后需要移除缓存中对该bean的正在加载状态的记录,同一个类中

 protected void afterSingletonCreation(String beanName) {
     if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
         throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
     }
 }

(6)将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态 同一个类中

protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
        this.singletonObjects.put(beanName, singletonObject);
        this.singletonFactories.remove(beanName);
        this.earlySingletonObjects.remove(beanName);
        this.registeredSingletons.add(beanName);
    }
}

(7)返回处理结果
虽然我们了解了加载bean的逻辑架构,但是现在我们并没有开始对bean加载功能进行探索,之前提到过,bean的加载逻辑实在传入的ObjectFactory类型的参数

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;
    }
});

[复制代码](javascript:void(0)😉

ObjectFactory的核心部分只调用了createBean()方法,继续探索createBean()

5.实例化bean

  • 实例化:指创建类实例(对象)的过程。比如使用构造方法new对象,为对象在内存中分配空间。(要创建对象,但是并未生成对象)
  • 初始化:指为类中各个类成员(被static修饰的成员变量)赋初始值的过程,是类生命周期中的一个阶段。简单理解为对象中的属性赋值的过程。(对象已经生成,为其属性赋值)
5.0流程图

在这里插入图片描述

/**
 * Central method of this class: creates a bean instance,
 * populates the bean instance, applies post-processors, etc.
 * @see #doCreateBean
 */
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {


    RootBeanDefinition mbdToUse = mbd;


    // 锁定class,根据设置的class属性或者根据beanName来解析Class,具体在实现逻辑在resolveBeanClass()方法中
    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();
    }


    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        // 给BeanPostProcessors一个机会来返回代理来替代真正的实例
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }

    try {
        // 真正的创建bean的代码在这个方法中
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }
}

[复制代码](javascript:void(0)😉

来看下具体步骤和功能
(1)根据设置的class属性或者是beanName来解析Class
(2)对override属性进行标记和验证
这个其实spring中没有override-method这样的配置,但是spring是存在lookup-method和replace-method的,而这两个配置的加载其实
就是将配置统一存放到BeanDefinition中的methodOverride属性里,这个函数的操作其实就是针对这两个属性
(3)应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作
(4)创建bean

5.1 处理override属性

prepareMethodOverrides()方法在org.springframework.beans.factory.support包下的AbstractBeanDefinition类中

    public void prepareMethodOverrides() throws BeanDefinitionValidationException {
        if (this.hasMethodOverrides()) {
            this.getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
        }

    }

//继续看prepareMethodOverride(mo)方法的源码,在同一个类中:

    protected void prepareMethodOverride(MethodOverride mo) {
        int count = ClassUtils.getMethodCountForName(this.getBeanClass(), mo.getMethodName());
        if (count == 0) {
            throw new BeanDefinitionValidationException("Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + this.getBeanClassName() + "]");
        } else {
            if (count == 1) {
                mo.setOverloaded(false);
            }

        }
    }

spring是存在lookup-method和replace-method的,而这两个配置的加载其实就是将配置统一存放到BeanDefinition中的methodOverride属性里,
这两个方法的实现原理是在bean实例化的时候检测到存在MethodOverride,会动态的为当前bean生成动态代理并使用对应的拦截器为bean做增强处理,
相关逻辑实现在bean的实例化部分详细及讲解
但是,对于方法的匹配来讲,如果一个类中存在若干个重载方法,那么,在函数调用及增强的时候,还需要根据参数类型进行匹配,来最终确认当前调用的是
哪个函数。但是,spring将一部分匹配工作在这里完成了,如果当前类中的方法只有一个,那么就设置重载方法没有重载,这样在后续调用的时候便可以直接
使用找到的方法,而不需要进行方法的参数匹配验证了,而且还可以提前对方法存在性进行验证。

5.2 实例化的前置处理
  1. https://blog.csdn.net/xuan_lu/article/details/106061931
  2. InstantiationAwareBeanPostProcessor
    该接口继承自BeanPostProcessor接口,并自定义如图方法。
    在这里插入图片描述
  • postProcessBeforeInstantiation 实例化前置处理 (对象未生成)
  • postProcessAfterInstantiation 实例化后置处理 (对象已经生成)
  • postProcessPropertyValues 修改属性值。(对象已经生成)
  1. BeanPostProcessor
    在这里插入图片描述
  • postProcessBeforeInitialization初始化前置处理 (对象已经生成)
  • postProcessAfterInitialization初始化后置处理 (对象已经生成)

在真正调用doCreat方法创建bean之前调用了一个代理的方法,resolveBeforeInstantiation(beanName, mbdToUse),对BeanDefinition中属性做了前置处理,

当前置处理返回的结果如果不为空,那么直接略过后续的bean的创建而直接返回结果,这一特性虽然很容易被忽略,但是起着至关重要的作用,我们熟悉的AOP功能
就是在这里判断的

org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类中resolveBeforeInstantiation方法

[复制代码](javascript:void(0)😉

@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    // 如果尚未被解析
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

[复制代码](javascript:void(0)😉

此方法中判断了该bean是否有InstantiationAwareBeanPostProcessors(),如果有,

就调用applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization进行处理

该方法若能返回结果,则直接跳过了createBean的流程

(1)实例化前的后处理应用
bean的实例化前调用,也就是将AbstractBeanDefinition转换为BeanWrapper前处理,给子类一个修改BeanDefinition的机会,也就是说,bean通过这个方法处理之后
可能不是我们之前的bean了

[复制代码](javascript:void(0)😉

@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

(2)实例化后的后处理应用
在讲解从缓存中获取单例bean的时候提过,spring中的规则是在bean的初始化后尽可能保证将注册的后处理器postProcessAfterInitialization方法应用到bean中,
因为如果返回的bean不为空,那么便不会再次经历普通bean的创建过程,所以只能在这里应用后处理器的postProcessAfterInitialization方法

[复制代码](javascript:void(0)😉

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

6 doCreateBean

0.流程图

在这里插入图片描述

(1)如果是单例,则需要首先清除缓存
(2)实例化bean,将BeanDefinition转换成BeanWrapper,转化是一个复杂过程,大致思路如下
1.如果存在工厂方法则使用工厂方法进行初始化
2.一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化
3.如果即不存在工厂方法,也没有指定构造方法,则使用指定的构造方法初始化bean
(3)MergedBeanDefinitionPostProcessors的应用
bean合并后处理,autowire注解正是通过此方法实现注入类型的预解析
(4)依赖处理
(5)属性填充。将所有属性填充到bean的实例中
(6)循环依赖检查
之前提到过,在spring中解决循环依赖只对单例有效,而对于prototype的bean,spring没有更好的解决办法,唯一要做的是抛出异常。
(7)注册DisposableBean
如果配置了destroy-method,这里需要注册以便于在销毁时候调用
(8)完成创建并返回

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

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    // 根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
    if (instanceWrapper == null) {
        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 {
                // 应用MergedBeanDefinitionPostProcessors
                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.isDebugEnabled()) {
            logger.debug("Eagerly caching bean '" + beanName +
                    "' to allow for resolving potential circular references");
        }
        //为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        // 对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖bean
        populateBean(beanName, mbd, instanceWrapper);
        // 初始化bean
        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) {
        Object earlySingletonReference = getSingleton(beanName, false);
        // earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
        if (earlySingletonReference != null) {
            // 如果exposedObject没有在初始化方法中被改变,也就是没有被增强
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
            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);
                    }
                }
                // 因为bean创建后其所依赖的bean一定已经创建的
                // actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有被全部创建完,存在循环依赖
                if (!actualDependentBeans.isEmpty()) {
                    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 {
        // 根据scope注册bean
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}
1 创建bean实例

首先从createBeanInstance()方法开始,这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    // 解析Class
    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());
    }

    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    // 如果工厂方法不为空则使用工厂方法初始化策略
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            // 一个类有多个构造函数,每个构造函数都有不同的参数,所以调用钱需要先根据参数锁定构造函数或者是工厂方法
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    // 如果已经解析过则使用解析好的构造函数不需要再次锁定
    if (resolved) {
        if (autowireNecessary) {
            // 构造函数自动注入
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            // 使用默认的构造函数
            return instantiateBean(beanName, mbd);
        }
    }

    // Candidate constructors for autowiring?
    // 需要根据参数解析构造函数
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        // 构造函数自动注入
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // No special handling: simply use no-arg constructor.
    // 使用默认构造函数构造
    return instantiateBean(beanName, mbd);
}

[复制代码](javascript:void(0)😉

大致梳理一下这个createBeanInstance()方法中的思路:
(1)如果在RootBeanDefinition中存在factoryMethodName属性,或者说是在配置文件中配置了factory-method,那么spring会尝试使用
instantiateUsingFactoryMethod(beanName, mbd, args)方法根据RootBeanDefiniton中配置生成bean的实例
(2)解析构造函数并进行构造函数的实例化,因为一个bean对应的类中可能会有多个构造函数,而每个构造函数的参数不同,spring会根据参数以及类型
去判断最终会使用哪个构造函数进行实例化。但是,判断过程是比较消耗性能的,所以采用缓存机制,如果已经解析过了,则不需要重复解析,而是直接从
RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值去取,否则需要再次解析,并将结果添加至RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod中

2记录创建bean的ObjectFactory

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f6txzD4w-1604735670476)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603891632091.gif)]](javascript:void(0)😉

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
        isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
    if (logger.isDebugEnabled()) {
        logger.debug("Eagerly caching bean '" + beanName +
                "' to allow for resolving potential circular references");
    }
    //为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        synchronized(this.singletonObjects) {
            if (!this.singletonObjects.containsKey(beanName)) {
                this.singletonFactories.put(beanName, singletonFactory);
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.add(beanName);
            }

        }
    }

[复制代码](javascript:void(0)😉

这一个小内容是来解释spring中处理依赖的方法的
(1)earlySingletonExposure,字面意思是提早曝光,哪些条件可以影响这个值呢?
(2)mbd.isSingleton():此RootBeanDefinition代表的是是否是单例
(3)this.allowCircularReferences:是否允许循环依赖
(4)isSingletonCurrentlyInCreation(beanName):该bean是否在创建中

3.依赖注入

属性注入的功能,主要是使用的populateBean()方法,看一下属性是如何注入
org.springframework.beans.factory.support包下的AbstractAutowireCapableBeanFactory类中

在这个处理方法中populateBean,主要处理流程是这样的:
(1)InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation来控制是否进行属性的填充
(2)根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues
(3)应用InstantiationAwareBeanPostProcessor处理器的postProcessPropertyValues方法,对属性获取完毕填充前对属性再次处理,典型应用是
org.springframework.beans.factory.annotation包下的RequiredAnnotationBeanPostProcessor
(4)将所有的PropertyValues中的属性填充至BeanWrapper中

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m7HAIhIC-1604735670478)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603891755779.gif)]](javascript:void(0)😉

/**
 * Populate the bean instance in the given BeanWrapper with the property values
 * from the bean definition.
 * @param beanName the name of the bean
 * @param mbd the bean definition for the bean
 * @param bw the BeanWrapper with bean instance
 */
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.
    // 给InstantiationAwareBeanPostProcessors最后一次机会在属性设置前改变bean
    // 例如:可以用来支撑属性注入的类型
    boolean continueWithPropertyPopulation = true;

    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // 返回值是否继续填充bean
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    continueWithPropertyPopulation = false;
                    break;
                }
            }
        }
    }

    // 如果后处理器发出停止填充命令则终止后续的执行
    if (!continueWithPropertyPopulation) {
        return;
    }

    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // Add property values based on autowire by name if applicable.
        // 根据名称自动注入
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // Add property values based on autowire by type if applicable.
        // 根据类型自动注入
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }

    // 后处理器已经初始化
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    // 需要依赖检查
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    if (hasInstAwareBpps || needsDepCheck) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        if (hasInstAwareBpps) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    // 对所有需要依赖的属性进行后处理
                    pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvs == null) {
                        return;
                    }
                }
            }
        }
        if (needsDepCheck) {
            // 依赖检查,对应depend-on属性 spring3.0废弃
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    }

    if (pvs != null) {
        // 将属性应用到bean中
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

[复制代码](javascript:void(0)😉

其中的有几个方法来看一下源码:
1、根据名称依赖注入 autowireByName
org.springframework.beans.factory.support包下的AbstractAutowireCapableBeanFactory类中

[复制代码](javascript:void(0)😉

/**
 * Fill in any missing property values with references to
 * other beans in this factory if autowire is set to "byName".
 * @param beanName the name of the bean we're wiring up.
 * Useful for debugging messages; not used functionally.
 * @param mbd bean definition to update through autowiring
 * @param bw the BeanWrapper from which we can obtain information about the bean
 * @param pvs the PropertyValues to register wired objects with
 */
protected void autowireByName(
        String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

    // 在bw中寻找需要依赖注入的属性
    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    for (String propertyName : propertyNames) {
        if (containsBean(propertyName)) {
            // 递归初始化相关的bean
            Object bean = getBean(propertyName);
            pvs.add(propertyName, bean);
            // 注册依赖
            registerDependentBean(propertyName, beanName);
            if (logger.isDebugEnabled()) {
                logger.debug("Added autowiring by name from bean name '" + beanName +
                        "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
            }
        }
        else {
            if (logger.isTraceEnabled()) {
                logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
                        "' by name: no matching bean found");
            }
        }
    }
}

[复制代码](javascript:void(0)😉

如果之前了解过autowire的使用方法,我也没有理解清楚这段代码,传入的参数pvs中找到已经加载的bean,并且递归实例化,进而加入到pvs中

2、根据类型自动注入 autowireByType

3、applyPropertyValues
程序运行到这里,已经完成了对所有注入属性的获取,但是获取的属性是以PropertyValues形式存在的,还并没有应用到已经实例化的bean中,这一工作在
applyPropertyValues函数中实现,org.springframework.beans.factory.support包下的AbstractAutowireCapableBeanFactory类中

[复制代码](javascript:void(0)😉

/**
 * Apply the given property values, resolving any runtime references
 * to other beans in this bean factory. Must use deep copy, so we
 * don't permanently modify this property.
 * @param beanName the bean name passed for better exception information
 * @param mbd the merged bean definition
 * @param bw the BeanWrapper wrapping the target object
 * @param pvs the new property values
 */
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    if (pvs.isEmpty()) {
        return;
    }

    // 系统验证
    if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
        ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
    }

    MutablePropertyValues mpvs = null;
    List<PropertyValue> original;

    if (pvs instanceof MutablePropertyValues) {
        mpvs = (MutablePropertyValues) pvs;
        // 如果mpvs中的值已经被转换为对应的类型,那么可以直接设置到BeanWrapper中
        if (mpvs.isConverted()) {
            // Shortcut: use the pre-converted values as-is.
            try {
                bw.setPropertyValues(mpvs);
                return;
            }
            catch (BeansException ex) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Error setting property values", ex);
            }
        }
        original = mpvs.getPropertyValueList();
    }
    else {
        // 如果pvs并不使用MutablePropertyValues封装的类型,那么直接使用原始的属性获取方法
        original = Arrays.asList(pvs.getPropertyValues());
    }

    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }
    // 获取对应的解析器
    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

    // Create a deep copy, resolving any references for values.
    List<PropertyValue> deepCopy = new ArrayList<>(original.size());
    boolean resolveNecessary = false;
    // 遍历属性,将属性转换为对应类的对应属性类型
    for (PropertyValue pv : original) {
        if (pv.isConverted()) {
            deepCopy.add(pv);
        }
        else {
            String propertyName = pv.getName();
            Object originalValue = pv.getValue();
            Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
            Object convertedValue = resolvedValue;
            boolean convertible = bw.isWritableProperty(propertyName) &&
                    !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
            if (convertible) {
                convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
            }
            // Possibly store converted value in merged bean definition,
            // in order to avoid re-conversion for every created bean instance.
            if (resolvedValue == originalValue) {
                if (convertible) {
                    pv.setConvertedValue(convertedValue);
                }
                deepCopy.add(pv);
            }
            else if (convertible && originalValue instanceof TypedStringValue &&
                    !((TypedStringValue) originalValue).isDynamic() &&
                    !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                pv.setConvertedValue(convertedValue);
                deepCopy.add(pv);
            }
            else {
                resolveNecessary = true;
                deepCopy.add(new PropertyValue(pv, convertedValue));
            }
        }
    }
    if (mpvs != null && !resolveNecessary) {
        mpvs.setConverted();
    }

    // Set our (possibly massaged) deep copy.
    try {
        // BeanWrapper中 wrapper的意思是包装纸的意思 这里大概就是bean的封装类
        bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }
    catch (BeansException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
}

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cgSx9jtK-1604735670483)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603891755779.gif)]](javascript:void(0)😉

4.初始化bean
(0)流程图

在这里插入图片描述

doCreateBean函数中有这样一行代码:这行代码中initializeBean函数就是初始化bean的逻辑
exposedObject = initializeBean(beanName, exposedObject, mbd);

这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4x7yLwN0-1604735670485)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603892753866.gif)]](javascript:void(0)😉

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        // 对特殊的bean处理:Aware、BeanClassLoader、BeanFactoryAware
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 应用后处理器
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 激活用户自定义的init方法
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        // 后处理器应用
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XiuY5S84-1604735670485)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603892753866.gif)]](javascript:void(0)😉

虽说此函数的目的主要是进行客户设定的初始化方法的调用,但是除此之外还有其他必要的工作

(1)激活Aware方法

理解一下Aware的使用,spring中提供了一些Aware接口,比如好多org.springframework.beans.factory,这个包下好多啊,实现这些Aware接口的bean被初始化之后
可以取得一些相应的资源,例如,实现BeanFactoryAware的bean在初始化后,spring容器会注入BeanFactory的实例,来看一下Aware的使用

[复制代码](javascript:void(0)😉

// 定义普通的bean
public class Hello{
    public void say(){
        System.out.println("hello");
    }
}

// 定义BeanFactoryAware类型的bean
public class Test implements BeanFactoryAware {
    private BeanFactory beanFactory;

    // 声明bean的时候spring会自动注入BeanFactory
    @override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public void testAware(){
        Hello hello = (Hello) beanFactory.getBean("hello");
        hello.say();
    }
}

[复制代码](javascript:void(0)😉

基本上就是这样使用的,看一下 源码:
这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下

[复制代码](javascript:void(0)😉

 1 private void invokeAwareMethods(final String beanName, final Object bean) {
 2     if (bean instanceof Aware) {
 3         if (bean instanceof BeanNameAware) {
 4             ((BeanNameAware) bean).setBeanName(beanName);
 5         }
 6         if (bean instanceof BeanClassLoaderAware) {
 7             ClassLoader bcl = getBeanClassLoader();
 8             if (bcl != null) {
 9                 ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
10             }
11         }
12         if (bean instanceof BeanFactoryAware) {
13             ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
14         }
15     }
16 }

[复制代码](javascript:void(0)😉

(2)处理器的应用

BeanPostProcessor是spring开放式架构中必不可少的亮点,给用户充足的权限去更改或者扩展spring,除了BeanPostProcessor,还有很多PostProcessor,
当然大部分都是以此为基础,继承组BeanPostProcessor,BeanPostProcessor的使用位置就是这里,在调用客户自定义初始方法前以及调用自定义初始方法后
分别会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization,使用户根据自己的需求进行自己处理
这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下

[复制代码](javascript:void(0)😉

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GsFxeLjf-1604735670492)(D:\Typora\java核心\A源码专题\spring\assets\copycode-1603892753866.gif)]](javascript:void(0)😉

(3)激活自定义的init方法

客户定制的初始化方法除了我们熟知的使用init-method配置外,还要使用自定义bean实现initializeBean接口,并在afterPropertiesSet中实现自己的初始化逻辑
init-method与afterPropertiesSet都是在初始化bean时执行,指定顺序是afterPropertiesSet先执行,init-method再执行

在invokeInitMethods方法中实现了这部分处理逻辑

[复制代码](javascript:void(0)😉

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {

    // 首先检查是否是InitializingBean,如果是的话就调用afterPropertiesSet()
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isDebugEnabled()) {
            logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                    ((InitializingBean) bean).afterPropertiesSet();
                    return null;
                }, getAccessControlContext());
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }

    if (mbd != null && bean.getClass() != NullBean.class) {
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
                !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
            // 调用自定义初始化方法
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

[复制代码](javascript:void(0)😉

5 注册DisposableBean

spring中不但提供了对于初始化方法的扩展入口,同样也提供了销毁的扩展入口,对于销毁方法的扩展,除了我们熟知的配置属性destroy-method方法,用户还
可以注册后处理器DestructionAwareBeanPostProcessor来统一处理bean的销毁方法

[复制代码](javascript:void(0)😉

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
        if (mbd.isSingleton()) {
            // Register a DisposableBean implementation that performs all destruction
            // work for the given bean: DestructionAwareBeanPostProcessors,
            // DisposableBean interface, custom destroy method.
            // 单例模式下注册需要销毁的bean,此方法中会处理实现DisposableBean的bean,
            // 并且对所有的bean使用DestructionAwareBeanPostProcessor处理DisposableBean
            registerDisposableBean(beanName,
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
        else {
            // A bean with a custom scope...
            // 自定义scope处理
            Scope scope = this.scopes.get(mbd.getScope());
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
            }
            scope.registerDestructionCallback(beanName,
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
    }
}

[复制代码](javascript:void(0)😉

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值