关于spring:Bean-的初始化过程

本文次要介绍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利用上下文,是更高级的容器,在简略容器的根底上减少了许多个性。

上图是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的后面曾经介绍过了一部分,这里次要介绍没有介绍过的。

最顶层的接口是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的初始化流程能够总结如下:

【腾讯云】轻量 2核2G4M,首年65元

阿里云限时活动-云数据库 RDS MySQL  1核2G配置 1.88/月 速抢

本文由乐趣区整理发布,转载请注明出处,谢谢。

您可能还喜欢...

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据