1

本文主要介绍Bean的初始化过程,在介绍Bean的初始化之前先介绍IOC容器的相关设计,因为Bean是在IOC容器中初始化的。

Spring IOC 容器

IOC 容器是Spring的基本组件,IoC 容器(又名DI 容器)是Spring 实现自动依赖注入的组件, Spring通过IOC 容器管理对象的创建及其生命周期,并向类注入依赖项。 IoC 容器可以创建指定类的对象,并在运行时通过构造函数、属性或方法注入所有依赖对象,并在适当的时候销毁它。

一般IOC容器需要具备一下功能:

  1. Bean的注册,需要告诉IOC容器需要管理哪些对象。
  2. Bean的解析,IOC容器需要解析出对象的依赖并根据配置进行依赖注入。
  3. Bean的生命周期管理,IOC容器需要管理Bean的生命周期。

Spring的IOC容器设计

在Spring IOC容器的设计中,可以看到两个主要的容器系列,一个是实现BeanFactory接口的简单容器系列,实现了容器的基本功能;另一个是ApplicationContext应用上下文,是更高级的容器,在简单容器的基础上增加了许多特性。

IOC.png

上图是Spring IOC容器的接口设计,不包含类之间的继承关系。

下面分别来看看各个接口定义的功能:

下面提到的方法都省去了入参和返回值。
  • BeanFactory: 主要定义了getBean()方法以及getBean()的重载方法用来获取某个Bean,除此之外还有getType()方法获取某个Bean的Class, containsBean()判断IOC容器是否含有某个Bean, isTypeMatch()用来判断Bean的类型是否与某个类型相匹配, isSingleton(), isPrototype()方法用来判读Bean的类型。
  • AutowireCapableBeanFactory: 主要定义了Autowire的功能。AutowireCapableBeanFactory继承了BeanFactory,同时新增了applyBeanPostProcessorsBeforeInitialization()和applyBeanPostProcessorsAfterInitialization()用于在Bean的初始化前后应用BeanPostProcessors,autowire() 用于Bean的自动绑定,createBean() 根据autowire模式创建一个完整的Bean,resolveDependency() 用于解析某个Bean的依赖,resolveNamedBean() 根据Bean的Class去获取一个Bean,包括Bean的名字,resolveBeanByName() 根据名字去获取一个Bean,destroyBean(), initializeBean()分别在Bean被销毁和创建完成调用,applyBeanPropertyValues() 将beanDefinition的属性应用到某个Bean中。
  • HierarchicalBeanFactory: 在BeanFactory的基础上新增了getParentBeanFactory()用于获取父BeanFactory, containsLocalBean() 用于判断当前的BeanFactory是否包含某个Bean,不包括父BeanFactoy。
  • ListableBeanFactory: 在BeanFactory的基础上增加了获取根据bean的class,注解获取beanName, bean的方法,返回的beanName或者bean可能有多个,因为满足条件的bean有多个,同时新增了跟beanDefinition有关的方法,containsBeanDefinition()判断是否含有某个beanName的BeanDefiniton, getBeanDefinitionCount()获取BeanDefinition的数量,getBeanDefinitionNames()获取BeanDefinition的名字。
  • ConfigurableBeanFactory:继承了HierarchicalBeanFactory, 提供了对beanFactory的配置功能,包括scope, parentBeanFactory, beanClassLoader, tempClassLoader, beanExpressionResolver, conversionService, propertyEditorRegister, typeConverter, beanPostProcessor等的设置。
  • ResourceLoader: 定义了加载资源(classPath下或者文件系统的资源)的方法,getResource()根据给定的location返回相应的Resource, getClassLoader()返回ResourceLoader的classLoader。
  • ResourcePatternResolver: 继承自ResourceLoader,定义了getResources(),通过解析location, 返回多个Resource。
  • MessageSource: 定义了消息解析的结构,三个参数不同的getMessage()的方法表示通过不同的方式进行消息的解析。
  • EnvironmentCapable: 定义了一个暴露Environment的方法getEnvironment()。
  • ApplicationEventPublisher: 定义了跟事件发布的方法publishEvent()。
  • ApplicationContext: 继承了EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver,意味着ApplicationContext是一个BeanFactory,同时支持设置parentBeanFactory, 事件发布,消息解析,资源解析等功能,除此之外还聚合了AutowireCapableBeanFactory,因此ApplicationContext比简单的BeanFactory拥有更多的功能。
  • ConfigurableApplicationContext: 在ApplicationContext的基础上继承了Lifecycle, 支持start, stop的生命周期的控制,同时定义了refresh()方法用于IOC容器的初始化。
  • WebApplicationContext: 在ApplicationContext的基础上新增了getServletContext()方法获取ServletContext。

以上就是Spring IOC 容器主要的接口设计,可以看到左边的为BeanFactory继承关系,右边的为Application的继承关系。

从上述的接口设计中,可以看到,在Spring 框架中提供了多个IOC容器,这里以DefaultListableBeanFactory为例来看Bean的初始化,DefaultListableBeanFactory 提供了IOC的基本功能,更多高级的IOC容器也是基于DefaultListableBeanFactory实现的。Bean的注册实际上就是BeanDefinition的加载过程,已经记录在BeanDefinition的加载过程

Bean初始化过程

同样先来看一下DefaultListableBeanFactory的整个继承关系,整个继承关系可以分为两部分,一部分于BeanFactory相关,一部分是Bean和BeanDefinition的相关。关于BeanFactory的前面已经介绍过了一部分,这里主要介绍没有介绍过的。

DefaultListableBeanFactory.png

最顶层的接口是AliasRegistry, 主要用来管理的Alias(中文翻译为别名)的。SimpleAliasRegistry类实现了AliasRegistry,并使用一个map保存了alias到canonical name(中文翻译为规范名)的映射。BeanDefinitionRegistry接口继承AliasRegistry,主要用来管理BeanDefinition。SingletonBeanRegistry接口主要用来管理singleton 类型的bean。DefaultSingletonBeanRegistry继承SimpleAliasRegistry和实现了SingletonBeanRegistry,提供了alias和bean的管理功能,保存了beanName到bean实例的映射,以及bean之间的依赖关系。FactoryBeanRegistrySupport在DefaultSingletonBeanRegistry提供了与FactoryBean集成的功能。AbstractBeanFactory 继承FactoryBeanRegistrySupport实现了ConfigurableBeanFactory,意味着AbstractBeanFactory 拥有了bean的注册,获取,移除,beanFactory的配置的功能。AbstractAutowireCapableBeanFactory 继承了AbstractBeanFactory实现了AutowireCapableBeanFactory, 实现了自动绑定(依赖注入)的功能。最后的DefaultListableBeanFactor继承自AbstractAutowireCapableBeanFactory,同时实现了ConfigurableListableBeanFactory, BeanDefinitionRegistry, 集BeanDefinition的管理,Bean的管理,BeanFactory的配置,依赖注入于一身。

同样以Spring中单元测试为例开始分析IOC容器初始化的过程:

@Test
void reregisterBeanDefinition() {
    DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
    RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
    bd1.setScope(BeanDefinition.SCOPE_PROTOTYPE);
    lbf.registerBeanDefinition("testBean", bd1);
    assertThat(lbf.getBean("testBean")).isInstanceOf(TestBean.class);
    RootBeanDefinition bd2 = new RootBeanDefinition(NestedTestBean.class);
    bd2.setScope(BeanDefinition.SCOPE_SINGLETON);
    lbf.registerBeanDefinition("testBean", bd2);
    assertThat(lbf.getBean("testBean")).isInstanceOf(NestedTestBean.class);
}

上述代码可以概括为以下几步:

  1. 创建一个RootBeanDefinition,并填充相应的属性,BeanDefinition的加载过程就是将xml文件或者注解转换为BeanDefinition。
  2. 将BeanDefinition 注册到BeanFactory里面。
  3. 获取一个Bean,真正开始Bean的初始化与注册。

前面两步很简单,就是创建一个TestBean 对应的BeanDefinition, 然后将BeanDefinition 注册到DefaultListableBeanFactory中去。DefaultListableBeanFactory实现了BeanDefinitionRegistry接口。

在分析getBean的方法之前,先来看一下DefaultListableBeanFactory的属性。

/** Whether to allow re-registration of a different definition with the same name. */
/** 是否允许注册相同的名称的不同的BeanDefinition */
private boolean allowBeanDefinitionOverriding = true;

/** Whether to allow eager class loading even for lazy-init beans. */
/**  对于懒加载的bean是否允许提前初始化  */
private boolean allowEagerClassLoading = true;

/** Optional OrderComparator for dependency Lists and arrays. */
@Nullable
private Comparator<Object> dependencyComparator;

/** Resolver to use for checking if a bean definition is an autowire candidate. */
/** 检查BeanDefinition是否是autowire的候选的解析器  */
private AutowireCandidateResolver autowireCandidateResolver = SimpleAutowireCandidateResolver.INSTANCE;

/** Map from dependency type to corresponding autowired value. */
/** 依赖类型到依赖注入的bean的映射 */
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);

/** Map of bean definition objects, keyed by bean name. */
/** beanName -> beanDefinition 的映射, 保存BeanDefinition */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

/** Map from bean name to merged BeanDefinitionHolder. */
/** beanName 到 merged BeanDefinition 的映射, merged BeanDefinition 一般是RootBeanDefinition, 如果一个BeanDefiniiton是ChildBeanDefinition, 那么mergedBeanDefinition就是它的paraent BeanDefinition  */
private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256);

/** Map of singleton and non-singleton bean names, keyed by dependency type. */
/** bean的依赖类型到bean的beanName的映射 */
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);

/** Map of singleton-only bean names, keyed by dependency type. */
/** bean Name 到 singletion 类型beanName的映射 */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);

/** List of bean definition names, in registration order. */
/** BeanDefiniiton的名字 */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

/** List of names of manually registered singletons, in registration order. */
/** 保存通过registerSingleton()方法手动注入的单例的Bean的名字,即不是Spring 自动注入的 */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);

可以看到DefaultListableBeanFactory的属性主要保存了beanName到BeanDefinition的映射,以及class type 到 beanName的映射。

接着看getBean()的实现。

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

protected <T> T doGetBean(
        String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
        throws BeansException {
    // 如果name带有"&"前缀,则去掉前缀
    // 尝试在bean的别名映射中根据name找到相应的相应的规范名
    // 如果没有,则就是原始的name
    String beanName = transformedBeanName(name);
    Object beanInstance;

    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isTraceEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                        "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
        // Fail if we're already creating this bean instance:
        // We're assumably within a circular reference.
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // Check if bean definition exists in this factory.
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                        nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else if (requiredType != null) {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
            else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }

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

        StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
                .tag("beanName", name);
        try {
            if (requiredType != null) {
                beanCreation.tag("beanType", requiredType::toString);
            }
            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // Guarantee initialization of beans that the current bean depends on.  保证当前bean依赖的其他bean已经初始化
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        // 如果存在循环依赖
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    // 保存依赖关系
                    registerDependentBean(dep, beanName);
                    try {
                        // 先初始化依赖的Bean
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // Create bean instance.
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                        // Explicitly remove instance from singleton cache: It might have been put there
                        // eagerly by the creation process, to allow for circular reference resolution.
                        // Also remove any beans that received a temporary reference to the bean.
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

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

            else {
                String scopeName = mbd.getScope();
                if (!StringUtils.hasLength(scopeName)) {
                    throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
                }
                Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        beforePrototypeCreation(beanName);
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        finally {
                            afterPrototypeCreation(beanName);
                        }
                    });
                    beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    throw new ScopeNotActiveException(beanName, scopeName, ex);
                }
            }
        }
        catch (BeansException ex) {
            beanCreation.tag("exception", ex.getClass().toString());
            beanCreation.tag("message", String.valueOf(ex.getMessage()));
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
        finally {
            beanCreation.end();
        }
    }

    return adaptBeanInstance(name, beanInstance, requiredType);
}

上面的代码大致可以分为以下几个部分:

  1. 将name转换为规划名,如果带有&前缀,则去掉,如果name是别名,则尝试从aliasMap中返回相应的规范名,如果都不是,则直接返回。
  2. getSingleton()尝试获取已经初始化的bean,如果获取到了就直接返回,否则下一步。
  3. 初始化Bean,分为prototype类型的bean,singletion类型的bean,以及其他类型的bean,三种的类型的bean的处理大同小异。

下面以singleton类型的bean为例继续往下看。

上面的代码中首先检查了当前的beanName是否处于正在创建状态的prototype的bean,AbstractBeanFactory中的prototypesCurrentlyInCreation 以及 DefaultSingletonBeanRegistry中的singletonsCurrentlyInCreation分别保存了正在创建的prototype类型和singleton类型的bean。然后检查是否包含存在父beanFactory,如果存在父BeanFactory且当前的BeanFactory不包含当前beanName,则尝试使用父BeanFactory的getBean()方法初始化bean。如果不存在父BeanFactory,首先将beanName保存在AbstractBeanFactory的alreadyCreated属性中,表示正在创建或者创建完成。接着获取beanName对应的merged BeanDefinition, 如果BeanDefinition没有RootBeanDefinition, 则不需要merge, 否则需要merge。获取到merged BeanDefinition会检查是不是"abstract",这里的abstract指的是自己不能初始化自己,而是自己作为一个parent去创建具体的child BeanDefinition。然后会检查BeanDefinition的depend, 避免在BeanDefiniton中存在循环依赖。 如果当前的BeanDefinition存在依赖,则会先通过getBean()初始化其依赖的bean。如果没有则继续初始化当前bean,继续判断当前的BeanDefinition是singleton的还是prototype或者其他的类型的。
下面以singleton为例,

// Create bean instance.
if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, () -> {
        try {
            return createBean(beanName, mbd, args);
        }
        catch (BeansException ex) {
            // Explicitly remove instance from singleton cache: It might have been put there
            // eagerly by the creation process, to allow for circular reference resolution.
            // Also remove any beans that received a temporary reference to the bean.
            destroySingleton(beanName);
            throw ex;
        }
    });
    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    synchronized (this.singletonObjects) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            if (this.singletonsCurrentlyInDestruction) {
                throw new BeanCreationNotAllowedException(beanName,
                        "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                        "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
            }
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<>();
            }
            try {
                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;
                }
                afterSingletonCreation(beanName);
            }
            if (newSingleton) {
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

从上面的代码中可以看到,我们给getSingleton()方法传入了一个实现了ObjectFactory接口的匿名对象。首先依旧会从singletonObjects中取bean实例,如果没有找到,会将beanName加入到singletonsCurrentlyInCreation中表示正在创建。之后就会通过ObjectFactory的getObject()方法进行创建。getObject()方法中调用AbstractAutowireCapableBeanFactory的createBean(beanName, mbd, args)来创建bean。
继续看AbstractAutowireCapableBeanFactory的createBean()方法。

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. 创建Class 对象
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    try {
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }

    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        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 {
        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);
    }
}

createBean()方法首先通过resolveBeanClass()方法来解析beanClass,然后准备当前BeanDefinition中的overides方法(lookup-method 或者 replace-method),主要是检查是否可以被override,同时判断该方法有没有被重载(如果该方法名对应的方法只有一个,则没有被重载。),如果不存在该方法,则需要抛出异常。
接下来如果存在InstantiationAwareBeanPostProcessor,会尝试调用postProcessBeforeInstantiation()方法做一个前置的处理,这里可能会返回一个bean实例,如果这里返回了bean示例,意味着bean被初始化了,接着执行BeanPostProcessor的postProcessAfterInitialization() 方法,对初始化的bean做一些后置处理,设置BeanDefinition的beforeInstantiationResolved属性,然后就可以返回了。

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

如果不存在InstantiationAwareBeanPostProcessor则会继续往下走,走到doCreateBean()方法,从名字可以看出来,这里开始真正的创建bean。

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

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args); // new 出一个实例,此时还没有进行自动注入
    }
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;  // 填充resolvedTargetType
    }

    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
        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;
        }
    }

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    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");
        }
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        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 " +
                            "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

大致可以分为以下几步:

  1. createBeanInstance()创建一个最原始的bean的示例,即没有进行依赖注入,也称为raw bean。
  2. 如果存在MergedBeanDefinitionPostProcessor,则执行applyMergedBeanDefinitionPostProcessors()
  3. 如果是earlySingletonExposure, 则执行addSingletonFactory(),将bean示例缓存到singletonFactories中,需要注意的是,此时依旧没有发生依赖注入。
  4. populateBean() 这里才是真正发生以来注入的地方,如果存在依赖,则进行注入。
  5. initializeBean() 这步做一些后置的处理,比如执行invokeAwareMethods(), applyBeanPostProcessorsBeforeInitialization(), invokeInitMethods(), applyBeanPostProcessorsAfterInitialization()等方法。

第一步createBeanInstance()会先判断是否有instanceSupplier, 然后判断是否有factoryMethod, 存在instanceSupplier 或者 factoryMehtod,则使用相应的方法去获取一个raw bean。如果不存在instanceSupplier 或者 factoryMehtod,则检查是否存在已经解析的resolvedConstructorOrFactoryMethod,如果存在则根据constructorArgumentsResolved来决定通过autowireConstructor()或者instantiateBean()l来创建raw bean。如果不存在解析好的resolvedConstructorOrFactoryMethod,则尝试通过SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors()方法去确定一个构造函数,如果有返回构造函数则通过autowireConstructor()创建raw bean,最后还会检查BeanDefinition是否指定了Preferred constructors,如果指定了,则使用Preferred constructor通过autowireConstructor()进行初始化,如果依旧没有,就没辙了,通过默认的无参构造函数创建raw bean。

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

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

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

创建了raw bean之后,第二步如果存在MergedBeanDefinitionPostProcessor,则尝试使用MergedBeanDefinitionPostProcessor去修改Merged BeanDefinition,比如AutowiredAnnotationBeanPostProcessor会在这一步去解析Autowire注解,这里可以对Merged BeanDefiniton 进行修改。

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
    for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
        processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
    }
}

第三步,如果是earlySingletonExposure, 则执行addSingletonFactory(),将bean示例缓存到singletonFactories中,需要注意的是,此时依旧没有发生依赖注入。对于Singleton类型的Bean而言,一般都是允许earlySingletonExposure的。

第四步,可能是相对复杂的一步了,这里对bean的属性进行填充,会发生依赖注入。

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.
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                return;
            }
        }
    }

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

    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        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;
    }

    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
                if (filteredPds == null) {
                    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                }
                pvsToUse = 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) {
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

首先会判断是否有InstantiationAwareBeanPostProcessor, 如果存在则会执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法,这里改变bean的状态,比如对某个属性进行注入。
接下来根据BeanDefinition的autowireMode来决定bean的依赖注入的方式,比如通过beanName, beanType进行依赖注入,对于AUTOWIRE_BY_NAME 的方式,则通过autowireByName()方法进行注入。

protected void autowireByName(
        String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    for (String propertyName : propertyNames) {
        if (containsBean(propertyName)) {
            Object bean = getBean(propertyName);
            pvs.add(propertyName, bean);
            registerDependentBean(propertyName, beanName);
            if (logger.isTraceEnabled()) {
                logger.trace("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");
            }
        }
    }
}

其中unsatisfiedNonSimpleProperties返回了一组不满足(指存在存在相应的writeMethod但是包含在BeanDefinition的属性列表里)的非简单的属性。对于返回的非简单属性,根据属性的名字去初始化相应的bean, 并保存到属性列表中,同时添加依赖。这里并没有注入初始化的bean,只是保存了下来。
autowireByType()的操作与autowireByName类似,只是根据属性的Type去初始化相应的bean。

继续初始化的流程,此时属性列表里面已经包含了前面的不满足的非简单属性,接下同样会判断有没有InstantiationAwareBeanPostProcessor,如果有,则执行InstantiationAwareBeanPostProcessor的postProcessProperties()的方法。对于AutowiredAnnotationBeanPostProcessor,这里会进行属性的依赖注入。

最后如果属性列表不为null, 则applyPropertyValues(),这一步会使用属性列表,会对简单属性赋值,也会进行依赖注入。

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;
        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 {
        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();
            if (originalValue == AutowiredPropertyMarker.INSTANCE) {
                Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
                if (writeMethod == null) {
                    throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
                }
                originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
            }
            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 {
        bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }
    catch (BeansException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
}

所以会判断属性列表有没有转换后,如果已经是转换后的属性列表,表示已经对属性进行过解析,则直接通过setPropertyValues()注入,否则构建一个BeanDefinitionValueResolver,通过这个resolver去解析属性列表,解析过程就是对不同的数据类型进行解析,比如基本数据类型,集合,对象应用等,解析的如果是对象引用,则会初始化相应的应用,所有的属性解析完成之后,同样通过setPropertyValues()进行注入。

最后一步initializeBean()对已经进行过依赖注入的bean做一些后置的处理。

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        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;
}

如果bean实现了相应的Aware接口,比如BeanNameAware, BeanClassLoaderAware, BeanFactoryAware等,回调相应的接口。然后如果存在BeanPostProcessor,则调用BeanPostProcessor的postProcessBeforeInitialization()的方法,如果bean实现了InitializingBean则调用afterPropertiesSet()方法,如果指定了initMethod,则调用initMethod方法,如果存在BeanPostProcessor,则调用BeanPostProcessor.postProcessAfterInitialization()方法。

最后如果bean指定了销毁方法,则将该bean加入到disposableBeans中,在销毁时回调。

至此,一个bean的创建就完成了,还有一些收尾操作,比如将bean从singletonsCurrentlyInCreation,singletonFactories中移除,添加到singletonObjects,registeredSingletons中。

bean已经存放在容器的属性里了,直接通过beanName去取即可,最后如果有传入type的话,会尝试做一下类型转换后再返回。

总结

整个bean的初始化流程可以总结如下:
image.png


风是客
19 声望1 粉丝