[源码]springboot源码中一窥BeanFactory接口getBean的实现细节

先聊聊IOC

IoC(Inversion of Control) 控制反转,是spring框架的精髓,简单来说,就是创建过程你不管,交给容器。与之对应的两个重要的类:

  • BeanFactory - 接口的定义,定义了最基础的操作接口,具体功能依赖实现类
  • ApplicationContext - 实现了BeanFactory,并扩展其功能

spring中的IOC

Spring以往通过xml文件加载bean,过程大致如下:

  • 通过 xml 文件加载,xml文件举例:
<bean id="hello" class="cn.test.service.Hello">
    <property name="content" value="hello"/>
</bean>
  • 加载相关属性
  • 反射实例化对象
  • xml中的autowire
    注意:xml中也可以配置 autowire 会自动注入,参数 byName,意思是通过name去寻找依赖,通过这个方式解决依赖的注入。
<!-- 通过设置 autowire 属性,我们就不需要像上面那样显式配置依赖了 -->
<bean name="serviceAutowire" class="cn.test.autowire.Service" autowire="byName"/>
  • 解决配置bean太多的问题 引入FactoryBean(注意不是BeanFactory)
  • ApplicationContextAware引入
    在我们的web程序中,用spring来管理各个实例(bean), 有时在程序中为了使用已被实例化的bean, 通常会用到这样的代码
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext-common.xml");  
AbcService abcService = (AbcService)appContext.getBean("abcService"); 

这会重新装载applicationContext-common.xml并实例化上下文bean,如果有些线程配置类也是在这个配置文件中,那么会造成做相同工作的的线程会被启两次。一次是web容器初始化时启动,另一次是上述代码显示的实例化了一次。当于重新初始化一遍,这样就产生了冗余。
解决方法
不用类似new ClassPathXmlApplicationContext()的方式,从已有的spring上下文取得已实例化的bean。通过ApplicationContextAware接口进行实现。

  • BeanPostProcessor 是 bean 实例化时的后置处理器,包含两个方法,其源码如下:
public interface BeanPostProcessor {
    // bean 初始化前的回调方法
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

    // bean 初始化后的回调方法    
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

BeanPostProcessor 是 Spring 框架的一个扩展点,通过实现 BeanPostProcessor 接口,我们就可插手 bean 实例化的过程。比如大家熟悉的 AOP 就是在 bean 实例后期间将切面逻辑织入 bean 实例中的,AOP 也正是通过 BeanPostProcessor 和 IOC 容器建立起了联系。

简单来说:Spring容器从xml配置、java注解、spring注解中读取bean配置信息,形成bean定义注册表,填充bean的相关属性,应用通过getBean方法可以获取其中的bean并实例化使用。
在Spring中,ClassPathXmlApplicationContext 的构造过程,实际就是 Spring IoC 的初始化过程,ClassPathXmlApplicationContext的继承关系如下图:


image.png

BeanFactory的getBean的实现细节

回到这个类最基础的一个方法,我们看getBean的过程是如何实现的。

获取bean

BeanFactory中只定义了接口,getBean(String)方法实现细节体现5个实现类中。


image.png
  • SimpleJndiBeanFactory - spring beanFactory接口的基于jndi的简单实现
  • StaticListableBeanFactory - 简化版的BeanFactory,由于未实现BeanDefinitionRegistry,所以并不支持BeanDefinition的注册操作
  • StubWebApplicationContext - WebApplicationContext的实现
  • AbstractApplicationContext - ApplicationContext是应用的配置中的核心接口,应用运行过程中是只读的,但是可以通过实现其中的接口来达到reload的目的,AbstractApplicationContext是ApplicationContext的抽象类。相比于简单的BeanFactory,ApplicationContext能在类内部检查特定的bean的定义,这个类会自动注册BeanFactoryPostProcessor和BeanPostProcessors和ApplicationListeners
  • AbstractBeanFactory - BeanFactory实现的一个抽象基类,我们重点研究。
GetBean过程:AbstractBeanFactory中doGetBean

继承关系如下


image.png

BeanFactory实现的一个抽象基类,同时实现了ConfigurableBeanFactory的SPI。这个方法的getBean的实现(实际逻辑在doGetBean中),如下。

    /**
     * 返回一个实例,实例可以是共享的,独立的或者是一个特定的bean
     * @param name: bean的名称
     * @param requiredType: bean的类型
     * @param args :其他参数集合,***仅仅用于创建新对象的时候,而不是获取一个已经存在的对象*** @Nullable 表示可以为空,不能为空用@NotNull修饰
     * @param typeCheckOnly:是否对象只是用来做类型检查而不是实际要用
     * @return bean的实例
     * @throws BeansException 如果bean不能被创建抛出异常
     */
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
                
        // 去掉间接引用,去别名,使得最后的beanName是一个最简的名称,举例:
        // 1 有的name名字用&开头,表示取FactoryBean本身,需要调用该方法。
        // 2 name是别名,也需要转为对应的beanName
        // 其中调用了BeanFactoryUtils中的方法,这个是bean操作的工具类,也很值得一读,加个todo
        final String beanName = transformedBeanName(name);
        Object bean;

        // 检查单例缓存,获取人工注册的单例从beanName-->getSingleton获得object-->getObjectForBeanInstance获取bean
        // sharedInstance 是从一个 Map<String, Object> singletonObjects结构中获取的对象,这个对象cache了bean name和bean instance的映射
        // 实际接口调用过程中,有一些获取不到,向前置earlySingletonObjects获取的处理细节,这里可以看源码
        Object sharedInstance = getSingleton(beanName);

        // 如果 sharedInstance = null,则说明缓存里没有对应的实例,表明这个实例还没创建。
       // BeanFactory 并不会在一开始就将所有的单例 bean 实例化好,而是在调用 getBean 获取bean的时候实例化,也就是 lazy加载
        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 + "'");
                }
            }
            // 条件1:如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。
            // 条件2:如果是FactoryBean,且&开头,是FactoryBean的解引用,返回FactoryBean,这个也是特殊的bean
            // 条件1,2不满足,如果sharedInstance是FactoryBean,调用getObjectFromFactoryBean这个函数从中获取Object
            // getObjectFromFactoryBean方法中调用doGetObjectFromFactoryBean,其中又调用factory.getObject()方法,这个方法是一个抽象接口,所有的Factory的实现类实现这个接口去create instance
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {
            // 进入这个分支,则表明 sharedInstance 可能为空,
            // 此时 beanName 对应的 bean未创建,或者在父类中创建
            // 如果当前的bean已经创建过(非父类),会返回失败,应该是循环引用导致的。
            // debug到代码内部,prototypesCurrentlyInCreation.set有个分支:else if (curVal instanceof String)不明白为什么要有这个分支,但是不影响后续阅读,这里加个todo。
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // 检查bean的定义是否已经出现在工厂中
            // 先检查父亲工厂中是否有
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // 没找到,就递归地向上寻找
                // 递归过程中根据不同的参数分治
                // getBean 方法有很多重载,工厂模式了解一下
                // 比如 getBean(String name, Object... args),我们在首次获取,某个 bean 时,可以传入用于初始化 bean 的参数数组(args)
                // BeanFactory 会根据这些参数,去匹配合适的构造方法构造 bean 实例。
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else if (requiredType != null) {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
                else {
                    return (T) parentBeanFactory.getBean(nameToLookup);
                }
            }

            // 用alreadyCreated保存需要创建的beanName,如果只是做typeCheck,可以不用创建bean
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }
                      
                        
            try {
                // 贯穿父子关系去获取RootBeanDefinition
                // RootBeanDefinition是BeanDefinition最常用地实现类,对应配置文件中bean元素标签。在配置文件中可以定义父<bean>和子<bean>,父<bean>用RootBeanDefiniton表示,子<bean>用ChildBeanDefinition表示。
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                // 当前版本spring-beans-5.1.10只是在检查 !mbd.isAbstract()
                checkMergedBeanDefinition(mbd, beanName, args);

                // 初始化bean的依赖,举例:初始化一个店铺,店铺内有基本的设施,店铺依赖设施,这里先检查设施能否初始化。
                // todo:这里有个好奇,setDependsOn什么时候被赋值的?
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        // 再次检查是否包含循环依赖
                        // 这里是最朴素的循环依赖检查逻辑,内部是深度优先遍历,
                        // 找到A的依赖B的集合set<B>,然后判断set<B>的每个元素的依赖集合中是否依赖A
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        // 给当前bean注册一个依赖bean,对应下面的dep,销毁顺序是:依赖bean销毁后,当前bean才被销毁
                        // 注册后,下次判断循环依赖有可以检查到这次新注册的这组依赖关系 
                        registerDependentBean(dep, beanName);
                        try {
                            // 递归调用自己,来做检查,好多冗余操作啊...
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // 创建bean的实例,其中核心方法是createBean和getObjectForBeanInstance,这一大段只不过是区分单例,原型和其他的处理情况而已。
                // todo: 有时间要再读读createBean和getObjectForBeanInstance的源码。
                // 单例情况
                if (mbd.isSingleton()) {
                    // 从匿名函数返回中获取单例对象
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            // 创建一个bean
                            // todo:create是一个抽象接口,具体的实现逻辑在子类中,这里以后有时间可以读一下源码
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // 从缓存中明确的移除单例:避免在创建流程中因为缓存导致的循环引用,同时移除任何关于这个bean的临时引用。
                            // 删除的位置包含singletonObjects,singletonFactories,earlySingletonObjects,registeredSingletons,disposableBeans,dependentBeanMap
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    // 从bean的实例中获取对象
                    // bean的实例可能是一个普通bean,也可能是FactoryBean,如果是普通Bean可以直接返回,如果是FactoryBean,需要从中再获取到bean的实例。这个方法前面也提到过
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

                // 如果是原型(参考原型模式的概念)
                else if (mbd.isPrototype()) {
                    // 如果是原型,创建一个新实例
                    Object prototypeInstance = null;
                    try {
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }

                else {
                    // 非单例,非原型的方式获取bean
                    // 获取作用域
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                    }
                    try {
                        Object scopedInstance = scope.get(beanName, () -> {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        });
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {
                        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",
                                ex);
                    }
                }
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }

        // 类型检查:判断需要的类型是否匹配实际的bean实例。
        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                // todo: 通过类型转化来判断是否类型匹配,这个方法的源码也值得一读。
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                return convertedBean;
            }
            catch (TypeMismatchException ex) {
                if (logger.isTraceEnabled()) {
                                        // todo: ClassUtils也是一个值得读源码的工具类
                    logger.trace("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

主要流程已经在代码的注释中写清楚了,重点的几个逻辑我再总结一下:
1 去掉间接引用,去别名,使得最后的beanName是一个最简的名称transformedBeanName(name)
2 检查单例缓存,获取人工注册的单例中获取对象,利用该对象生成bean,生成方法中区分对待一般的bean和FactoryBean
3 第2步骤如果为null,从父类中获取bean和FactoryBean
4 父类中没有的话合并 BeanDefinition
5 处理 depends-on 依赖
6 创建并缓存 bean
7 调用 getObjectForBeanInstance 方法,生成 bean 实例
8 类型检查和转化

CreateBean过程

看上述核心代码,我们不难发现,有一个核心函数getSingleton一直在被调用

image.png

这个方法中传入了一个匿名函数,匿名函数中调用createBean,这是我们创建bean 的一段核心逻辑。我们先来看下getSingleton的代码逻辑


public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            // 缓存中获取bean,不为空则直接返回
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }

                // beforeSingletonCreation 将bean添加到 singletonsCurrentlyInCreation 的集合中,集合中存放的是正在创建的bean
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    // Has the singleton object implicitly appeared in the meantime ->
                    // if yes, proceed with it since the exception indicates that state.
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw ex;
                    }
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    // 创建完成,将bean从正在创建的集合中移除
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    // 将 <beanName, singletonObject> 映射缓存到 singletonObjects中
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }

总结一下上述过程:

  • 1 从singletonObjects获取能获取则直接获取,singletonObjects可以看作缓存
  • 2 不能获取进入创建流程,先将 beanName 添加到 singletonsCurrentlyInCreation
  • 3 getObject 调用 createBean 方法,创建bean
  • 4 beanName 从 singletonsCurrentlyInCreation 中移除
  • 5 <beanName, singletonObject> 添加至 singletonObjects

createBean是流程中创建bean的核心方法,我们继续看下这个createBean方法的实现。可以搜一下以下函数

return createBean(beanName, mbd, args);

在AbstractBeanFactory中只定义了一个抽象接口

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

接口的实现在AbstractAutowireCapableBeanFactory中的createBean方法
createBean方法和getBean方法有一些类似,就是真正getBean前后都做了很多事情,getBean的核心逻辑封装在另外一个方法中。
这里就不帖详细的源码了,整个代码结构就是如下形式:

  • pre-createBean:
    • 解析bean的类型
    • prepareMethodOverrides,override method的处理,实际在处理lookup-method 和 replace-method 配置(bean配置中的两个关键字)
    • 初始化前应用后置处理 resolveBeforeInstantiation,后置处理返回的 bean 不为空,则直接返回(这里也可能返回bean)
  • 核心逻辑:Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  • post-createBean:日志记录,返回对象

resolveBeforeInstantiation会生成bean,但是我们这里先不聊,因为和AOP原理相关,这里先不扩展,另外一个生成bean的核心逻辑写在doCreateBean中。我们具体看这个方法的实现。
ps:spring框架中,真实的执行逻辑一般都放在do开头的方法中,doCreateBean也是一样。

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

        // bean初始化
        // BeanWrapper 是bean 的包装类,通过这个包装,能方便的设置和获取bean的实例属性
        BeanWrapper instanceWrapper = null;

        // 单例先从factoryBeanInstanceCache移除,返回为null表示不存在,那么直接用createBeanInstance创建
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            // createBeanInstance创建createBean,使用三种策略之一:
            // factory method, constructor autowiring 或者 simple instantiation
            // factory method, 工厂方法
            // constructor autowiring,构造方式自动注入
            // simple instantiation,通过无参数构造方法
            // 另外bean的信息配置了lookup-method和replace-method会另外处理。
            // 返回类型是BeanWrapper,能用于填充对象的属性,todo:BeanWrapper的源码也值得读一读。
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        // 原始的bean,还没有填充属性
        final Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        // 允许后置处理器post-processors 修改 MBD
        synchronized (mbd.postProcessingLock) {
            // postProcessed默认为false
            if (!mbd.postProcessed) {
                try {
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

        // 缓存单例用于解决循环依赖,earlySingletonExposure用于表示是否提前暴露,即使生命周期处理接口带来的循环依赖也包含
        // earlySingletonExposure的满足的条件:
        // 条件: bean 是否是单例类型 & 允许循环依赖 &  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引用,如果bean中的方法被AOP切点匹配到,会进入aop相关逻辑
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // 初始化bean的实例
        Object exposedObject = bean;
        try {
            // 给bean装载属性,也是一个核心方法,todo:值得一读的源码
            populateBean(beanName, mbd, instanceWrapper);
            // 剩余的初始化工作
            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);
            if (earlySingletonReference != null) {
                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);
                        }
                    }
                    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.");
                    }
                }
            }
        }

        // 注册bean,为当前bean的销毁提供策略和实现
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }

以上创建过程给各小结:

  • 缓存中获取BeanWrapper,获取不到就创建BeanWrapper
  • 一些预处理,MergedBeanDefinitionPostProcessor; 暴露 bean 的早期引用(early reference),用于处理循环依赖问题
  • populateBean填充属性
  • initializeBean进行剩下的初始化
  • 注册销毁逻辑

createBeanInstance

doCreateBean这个方法中,有个很重要的核心方法createBeanInstance。
复述一下前面的批注:
createBeanInstance创建createBean,使用三种策略之一:

  • factory method, constructor autowiring 或者 simple instantiation
  • factory method, 工厂方法
  • constructor autowiring,构造方式自动注入
  • simple instantiation,通过无参数构造方法,另外bean的信息配置了lookup-method和replace-method会另外处理。返回类型是BeanWrapper,能用于填充对象的属性
instanceWrapper = createBeanInstance(beanName, mbd, args);

下面重点剖析这段代码

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // Make sure bean class is actually resolved at this point.
        Class<?> beanClass = resolveBeanClass(mbd, beanName);
        // 检测访问权限,默认情况下,对于public的类有访问权限,没有访问权限抛出异常
        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);
        }

        // 工厂方法不为空,通过工厂方法构建bean对象
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // Shortcut when re-creating the same bean...
        // 如果是处理同一个bean,第一次处理的时候,做个标记,之后同类型的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 {
                // 默认方法构造bean对象
                return instantiateBean(beanName, mbd);
            }
        }

        // 通过后处理器返回一系列构造方法
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        // 条件mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR:bean的autowire属性是否为constructor
        // 条件mbd.hasConstructorArgumentValues(): bean中是否配置了<construct-arg/>
        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.
        return instantiateBean(beanName, mbd);
    }

autowireConstructor

上面的代码通过不同的条件选择调用autowireConstructor,
这个方法比较复杂,到了这一步已经大致知道创建过程是如何的了,
这一层后续继续详解吧。
springboot中BeanWrapper的生成方法autowireConstructor

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容