spring源码深度解析---bean的加载(下)

spring源码深度解析—bean的加载(下)

我们继续接着之前的两篇bean的加载继续分析bean的实例创建

1. 创建bean实例

上面介绍了循环依赖还后置处理器处理的操作后接下来就到了创建bean的操作了,创建bean是在方法doCreateBean(beanName, mbdToUse, args)完成的,我们看下方法体:

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

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                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.isDebugEnabled()) {
            logger.debug("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 " +
                            "'getBeanNamesOfType' 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;
}

我们首先从createBeanInstance方法开始。方法代码如下:

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);
    }
}
// Need to determine the constructor...
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
        mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
    return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}

通过源码看到实际创建bean实例是在方法instanceWrapper = createBeanInstance(beanName, mbd, args)中完成的,我们深入方法体:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 解析class
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }
    //如果存在工厂方法则使用工厂方法进行初始化  
    //如果在RootBeanDefinition中存在factoryMethodName属性,或者说在配置文件中配置了  
    //factory-method,那么Spring会尝试使用instantiateUsingFactoryMethod(beanName, mbd, args)  
    //方法根据RootBeanDefinition中的配置生成bean的实例。  
    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;
            }
        }
    }
    //如果已经解析过则使用解析好的构造函数方法不需要再次锁定  
    //一个类中有多个构造函数,判断使用哪个构造函数实例化过程比较耗性能,所以采用缓存机制,如果已经解析过则不需要重复解析而是直接从RootBeanDefinition中的属性   
    //resolvedConstructorOrFactoryMethod缓存的值去取,否则需要再次解析,并将解析的结果添加至RootBeanDefinition中的属性
    //resolvedConstructorOrFactoryMethod中。 
    if (resolved) {
        if (autowireNecessary) {
            //构造函数自动注入
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            //使用默认构造函数构造 
            return instantiateBean(beanName, mbd);
        }
    }
    // Need to determine the constructor...
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null ||
            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
        return autowireConstructor(beanName, mbd, ctors, args);
    }
    // No special handling: simply use no-arg constructor.
    return instantiateBean(beanName, mbd);
}

我们看到代码中实例化的细节非常复杂,但是在createBeanInstance方法中我们还是可以清晰的看到实例化的逻辑的,总结如下:
(1)如果在RootBeanDefinition中存在factoryMethodName属性,或者再配置文件中配置了factory-method,那么spring会尝试使用instantiateUsingFactoryMethod(beanName, mbd, args)方法根据RootBeanDefinition中的配置生成实例。
(2)解析构造函数并行构造函数的实例化,因为一个bean可能会有多个构造函数,而每个构造函数的参数不同,spring在根据参数及类型去判断最终会使用哪个构造函数进行实例化。而这个判断过程非常的消耗性能,因此spring采用了缓存机制,如果已经解析过了则不需要充分解析而直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod中去取,否则需要再次解析,并将解析结果添加到RootBeanDefinition的resolvedConstructorOrFactoryMethod中。

1.1 autowireConstructor

对于实例的创建Spring中分成了两种情况,一种是通用的实例化,另一种是带有参数的实例化。带有参数的实例化过程相当复杂,因为存在着不确定性,所以在判断对应参数上做了大量工作。

public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
        @Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {

    BeanWrapperImpl bw = new BeanWrapperImpl();
    this.beanFactory.initBeanWrapper(bw);

    Constructor<?> constructorToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;
    //explicitArgs通过getBean方法传入  
    //如果getBean方法调用的时候指定方法参数那么直接使用  
    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    }
    else {
        //如果getBean方法时候没有指定则尝试从配置文件中解析
        Object[] argsToResolve = null;
        synchronized (mbd.constructorArgumentLock) {
            constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                // Found a cached constructor...
                argsToUse = mbd.resolvedConstructorArguments;
                if (argsToUse == null) {
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }
        //如果缓存中存在
        if (argsToResolve != null) {
            //解析参数类型,如给定方法的构造函数A(int,int)则通过此方法后就会把配置中的("1","1")转换为(1,1)  
            //缓存中的值可能是原始值也可能是最终值
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
        }
    }
    //没有被缓存 
    if (constructorToUse == null) {
        // Need to resolve the constructor.
        boolean autowiring = (chosenCtors != null ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
        ConstructorArgumentValues resolvedValues = null;

        int minNrOfArgs;
        if (explicitArgs != null) {
            minNrOfArgs = explicitArgs.length;
        }
        else {
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
            resolvedValues = new ConstructorArgumentValues();
            minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
        }

        // Take specified constructors, if any.
        Constructor<?>[] candidates = chosenCtors;
        if (candidates == null) {
            Class<?> beanClass = mbd.getBeanClass();
            try {
                candidates = (mbd.isNonPublicAccessAllowed() ?
                        beanClass.getDeclaredConstructors() : beanClass.getConstructors());
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Resolution of declared constructors on bean Class [" + beanClass.getName() +
                        "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
            }
        }
        AutowireUtils.sortConstructors(candidates);
        int minTypeDiffWeight = Integer.MAX_VALUE;
        Set<Constructor<?>> ambiguousConstructors = null;
        LinkedList<UnsatisfiedDependencyException> causes = null;

        for (Constructor<?> candidate : candidates) {
            Class<?>[] paramTypes = candidate.getParameterTypes();

            if (constructorToUse != null && argsToUse.length > paramTypes.length) {
                // Already found greedy constructor that can be satisfied ->
                // do not look any further, there are only less greedy constructors left.
                break;
            }
            if (paramTypes.length < minNrOfArgs) {
                continue;
            }

            ArgumentsHolder argsHolder;
            if (resolvedValues != null) {
                try {
                    String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
                    if (paramNames == null) {
                        ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                        if (pnd != null) {
                            paramNames = pnd.getParameterNames(candidate);
                        }
                    }
                    argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
                            getUserDeclaredConstructor(candidate), autowiring);
                }
                catch (UnsatisfiedDependencyException ex) {
                    if (this.beanFactory.logger.isTraceEnabled()) {
                        this.beanFactory.logger.trace(
                                "Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
                    }
                    // Swallow and try next constructor.
                    if (causes == null) {
                        causes = new LinkedList<>();
                    }
                    causes.add(ex);
                    continue;
                }
            }
            else {
                // Explicit arguments given -> arguments length must match exactly.
                if (paramTypes.length != explicitArgs.length) {
                    continue;
                }
                argsHolder = new ArgumentsHolder(explicitArgs);
            }

            int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                    argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
            // Choose this constructor if it represents the closest match.
            if (typeDiffWeight < minTypeDiffWeight) {
                constructorToUse = candidate;
                argsHolderToUse = argsHolder;
                argsToUse = argsHolder.arguments;
                minTypeDiffWeight = typeDiffWeight;
                ambiguousConstructors = null;
            }
            else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
                if (ambiguousConstructors == null) {
                    ambiguousConstructors = new LinkedHashSet<>();
                    ambiguousConstructors.add(constructorToUse);
                }
                ambiguousConstructors.add(candidate);
            }
        }

        if (constructorToUse == null) {
            if (causes != null) {
                UnsatisfiedDependencyException ex = causes.removeLast();
                for (Exception cause : causes) {
                    this.beanFactory.onSuppressedException(cause);
                }
                throw ex;
            }
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Could not resolve matching constructor " +
                    "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
        }
        else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Ambiguous constructor matches found in bean '" + beanName + "' " +
                    "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
                    ambiguousConstructors);
        }

        if (explicitArgs == null) {
            argsHolderToUse.storeCache(mbd, constructorToUse);
        }
    }

    try {
        final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
        Object beanInstance;

        if (System.getSecurityManager() != null) {
            final Constructor<?> ctorToUse = constructorToUse;
            final Object[] argumentsToUse = argsToUse;
            beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
                    strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
                    beanFactory.getAccessControlContext());
        }
        else {
            beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
        }

        bw.setBeanInstance(beanInstance);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Bean instantiation via constructor failed", ex);
    }
}

方法体代码量很大,但是这个方法不太符合spring的一贯风格,spring的一贯作风是将复杂的逻辑分解成N个小的函数,每一层都是对下一层的逻辑的总结及概要,这样使得每一层的逻辑变的简单且容易理解。而上面的函数则包含了许多的逻辑实现。我吗就简单的分析下函数:
(1)首先是构造函数参数的确定
根据explicitArgs参数来判断
如果传入的explicitArgs不为空,则可以直接确定参数,因为explicitArgs是在调用bean的时候用户指定的,在BeanFactory类中存在这样的方法:

Object getBean(String name,Object... args) throws BeansException;

在获取bean的时候,用户不但可以指定bean的名称还可以指定bean锁对应类的构造函数或者工厂方法的方法参数,主要用于静态工厂方法调用,而这里是需要给定完全匹配的参数。所以便可以判断如果传入的explicitArgs不为空就可以确定构造函数的参数。
缓存中获取
确定参数的方法如果直接已经分析过了,也就是说构造函数参数已经记录在缓存中,那可以直接从缓存中读取。这里需要注意,在缓存中存的可能是参数的最终类型也可能是参数的初始类型,所以即使在缓存中得到了参数也需要经过类型转换器的过滤。
配置文件中获取
如果不能根据传入的参数explicitArgs确定构造函数的参数也无法在缓存中得到,那就需要分享配置文件中的配置的构造函数的信息。在spring中配置文件的信息经过转换后都会保存在BeanDefinition中,也就是参数mbd中,因此可以调用mbd.getConstructorArgumentValues()来获取配置的构造函数信息。有了配置中的信息就可以获取对应的参数值信息了。
(2)构造函数的确定
经过了第一步后已经确定了构造函数的参数,接下来就是根据参数来锁定对应的构造函数,而匹配的方法就是根据参数个数匹配,所以在匹配之前需要先对构造函数按照public构造函数优先参数数量降序、非public构造函数参数数量降序。这样可以在遍历的情况下迅速判断排在后面的构造函数参数个数是否符合条件。
由于配置文件中并不是唯一限制使用参数位置索引的方式去创建,同样还支持指定参数名称进行设定参数值的情况,如,这种情况需要先确定构造函数中的参数名称。
获取参数名称有两种方式,一种是通过注解的方式直接获取,另一种是使用spring中提供的工具类ParameterNameDiscoverer来获取。构造函数、参数名称、参数类型、参数值都确定后就可以锁定构造函数及转换对应的参数类型。
(3)根据确定的构造函数转换对应的参数类型
主要是spring中提供的类型转换器或者用户提供的自定义类型转换器进行转换
(4)构造函数不确定性验证
有时候即使构造函数、参数名称、参数类型、参数值确定后也不一定会直接锁定构造函数,因为不同的构造函数的参数为父子关系,所以spring在最后又做了一次验证
(5)根据实例化策略以及得到的构造函数及参数实例化bean。

1.2 instantiateBean

经历了有参的实例构造,不带参数的构造函数的实例化过程就容易理解多了,使用的方法是instantiateBean(beanName, mbd),我们看下源码;

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        final BeanFactory parent = this;
        if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
                    getInstantiationStrategy().instantiate(mbd, beanName, parent),
                    getAccessControlContext());
        }
        else {
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
        }
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        initBeanWrapper(bw);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}

这个方法中并没有什么实质性的逻辑,带有参数的实例构造中,Spring把精力都放在了构造函数以及参数匹配上,如果没有参数的话,直接调用实例化策略进行实例化就可以了。

2. 实例化策略

实例化过程中,反复提到了实例化策略,这是做什么的呢?其实,经过前面的分析,我们已经得到了足以实例化的相关信息,完全可以使用最简单的反射方法来构造实例对象,但Spring却没有这么做。
接下来我们看下Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)方法,具体的实现是在SimpleInstantiationStrategy中,具体代码如下:

@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // Don't override the class with CGLIB if no overrides.
    if (!bd.hasMethodOverrides()) {
        Constructor<?> constructorToUse;
        synchronized (bd.constructorArgumentLock) {
            constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse == null) {
                final Class<?> clazz = bd.getBeanClass();
                if (clazz.isInterface()) {
                    throw new BeanInstantiationException(clazz, "Specified class is an interface");
                }
                try {
                    if (System.getSecurityManager() != null) {
                        constructorToUse = AccessController.doPrivileged(
                                (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
                    }
                    else {
                        constructorToUse =  clazz.getDeclaredConstructor();
                    }
                    bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                }
                catch (Throwable ex) {
                    throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                }
            }
        }
        return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
        // Must generate CGLIB subclass.
        return instantiateWithMethodInjection(bd, beanName, owner);
    }
}

Spring可谓是用心良苦,为了能更方便的使用Spring,程序中首先判断如果beanDefinition.getMethodOverrides()为空,也就是用户没有使用replace或者lookup的配置方法,那么直接使用反射的方式,简单快捷,但如果使用了这两个特性,再直接使用反射的方式创建实例就不妥了,因为需要将这两个配置提供的功能切入进去,所以就必须要使用动态代理的方式将包含两个特性锁对应的逻辑的拦截增强器设置进去,这样才可以保证在调用方法的时候会被相应的拦截器增强,返回值为包含拦截器的代理实例

3. 记录创建bean的ObjectFactory

在doCreateBean方法中有下面一段代码:

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isDebugEnabled()) {
            logger.debug("Eagerly caching bean '" + beanName +
                    "' to allow for resolving potential circular references");
        }
        //为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂  
        //依赖处理:在Spring中会有循环依赖的情况,例如,当A中含有B的属性,而B中又含有A的属性时就会  
        //构成一个循环依赖,此时如果A和B都是单例,那么在Spring中的处理方式就是当创建B的时候,涉及  
        //自动注入A的步骤时,并不是直接去再次创建A,而是通过放入缓存中的ObjectFactory来创建实例,  
        //这样就解决了循环依赖的问题。
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

这段代码不是很复杂,但很难以让人理解这段代码的作用,而且这段代码从此函数中去理解和很难弄懂其含义,我们需要从全局的角度去考虑Spring的依赖解决办法。
earlySingletonExposure:从字面的意思理解就是提早曝光的单例,我们暂不定义它的学名叫什么,我们感兴趣的是有那些条件影响这个值。
mbd.isSingleton():没有太多可以理解的,此RootBeanDefinition代表的是否单例。
this.allowCircularReferences:是否允许循环依赖,很抱歉,并没有找到在配置文件中如何配置,但是在AbstractRefreshableApplicationContext中提供了设置函数,可以通过硬编码的方式进行设置或者可以通过自定义命名空间进行配置,其中硬编码方式代码如下:

ClassPathXmlApplicationContext bf = new ClassPathXmlApplicationContext("aspectTest.xml");  
bf.setAllowBeanDefinitionOverriding(false);  

isSingletonCurrentlyInCreation(beanName):该bean是否在创建中。在Spring中,会有个专门的属性默认为DefaultSingletonBeanRegistry的singletonsCurrentlyInCreation来记录bean的加载状态,在bean开始创建前会将beanName记录在属性中,在bean创建结束后会将beanName移除。那么我们跟随代码一路走下来可以对这个属性的记录并没有多少印象,这个状态是在哪里记录的呢?不同scope的记录位置不一样,我们以singleton为例,在singleton下记录属性的函数是在DefaultSingletonBeanRegistry类的public Object getSingleton(String beanName,ObjectFactory singletonFactory)函数的beforeSingletonCreation(beanName)和afterSingletonCreation(beanName)中,在这两段函数中分别this.singletonsCurrentlyInCreation.add(beanName)与this.singletonsCurrentlyInCreation.remove(beanName)来进行状态的记录与移除。
经过以上的分析我们了解变量earlySingletonExposure是否是单例,是否允许循环依赖,是否对应的bean正在创建的条件的综合。当这3个条件都满足时会执行addSingletonFactory操作,那么加入SingletonFactory的作用是什么?又是在什么时候调用的?
我们还是以最简单AB循环为例,类A中含有属性B,而类B中又会含有属性A,那么初始化beanA的过程如下:
这里写图片描述
上图展示了创建BeanA的流程,在创建A的时候首先会记录类A所对应额beanName,并将beanA的创建工厂加入缓存中,而在对A的属性填充也就是调用pupulateBean方法的时候又会再一次的对B进行递归创建。同样的,因为在B中同样存在A属性,因此在实例化B的populateBean方法中又会再次地初始化B,也就是图形的最后,调用getBean(A).关键是在这里,我们之前分析过,在这个函数中并不是直接去实例化A,而是先去检测缓存中是否有已经创建好的对应的bean,或者是否已经创建的ObjectFactory,而此时对于A的ObjectFactory我们早已经创建,所以便不会再去向后执行,而是直接调用ObjectFactory去创建A.这里最关键的是ObjectFactory的实现。

addSingletonFactory(beanName, new ObjectFactory<Object>() {  
                public Object getObject() throws BeansException {  
                    //对bean再一次依赖引用,主要应用SmartInstantiationAware BeanPostProcessor,  
                    //其中我们熟知的AOP就是在这里将advice动态植入bean中,若没有则直接返回bean,不做任何处理  
                    return getEarlyBeanReference(beanName, mbd, bean);  
                }  
            });  

其中getEarlyBeanReference的代码如下:

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {  
        Object exposedObject = bean;  
        if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {  
            for (BeanPostProcessor bp : getBeanPostProcessors()) {  
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {  
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;  
                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);  
                    if (exposedObject == null) {  
                        return exposedObject;  
                    }  
                }  
            }  
        }  
        return exposedObject;  
    }

在getEarlyBeanReference函数中除了后处理的调用外没有别的处理工作,根据分析,基本可以理清Spring处理循环依赖的解决办法,在B中创建依赖A时通过ObjectFactory提供的实例化方法来获取原始A,使B中持有的A仅仅是刚刚初始化并没有填充任何属性的A,而这初始化A的步骤还是刚刚创建A时进行的,但是因为A与B中的A所表示的属性地址是一样的所以在A中创建好的属性填充自然可以通过B中的A获取,这样就解决了循环依赖的问题。

4. 属性注入

在了解循环依赖的时候,我们曾经反复提到了populateBean这个函数,也多少了解了这个函数的主要功能就是属性填充,那么如何实现填充呢?其源码如下:

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {  
        PropertyValues pvs = mbd.getPropertyValues();  

        if (bw == null) {  
            if (!pvs.isEmpty()) {  
                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.  
        boolean continueWithPropertyPopulation = true;  

        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {  
            for (BeanPostProcessor bp : getBeanPostProcessors()) {  
                if (bp instanceof InstantiationAwareBeanPostProcessor) {  
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  
                    //返回值为是否继续填充bean  
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {  
                        continueWithPropertyPopulation = false;  
                        break;  
                    }  
                }  
            }  
        }  
        //如果后处理器发出停止填充命令则终止后续的执行  
        if (!continueWithPropertyPopulation) {  
            return;  
        }  

        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||  
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);  

            // Add property values based on autowire by name if applicable.  
            //根据名称自动注入  
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {  
                autowireByName(beanName, mbd, bw, newPvs);  
            }  

            // Add property values based on autowire by type if applicable.  
            //根据类型自动注入  
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
                autowireByType(beanName, mbd, bw, newPvs);  
            }  

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

        if (hasInstAwareBpps || needsDepCheck) {  
            PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);  
            if (hasInstAwareBpps) {  
                for (BeanPostProcessor bp : getBeanPostProcessors()) {  
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {  
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  
                        //对所有需要依赖检查的属性进行后处理  
                        pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);  
                        if (pvs == null) {  
                            return;  
                        }  
                    }  
                }  
            }  
            if (needsDepCheck) {  
                //依赖检查,对应depends-on属性,3.0已经弃用此属性  
                checkDependencies(beanName, mbd, filteredPds, pvs);  
            }  
        }  
        //将属性应用到bean中  
        //将所有ProtertyValues中的属性填充至BeanWrapper中。  
        applyPropertyValues(beanName, mbd, bw, pvs);  
    }  

我们详细分析下populateBean的流程:
(1)首先进行属性是否为空的判断
(2)通过调用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)方法来控制程序是否继续进行属性填充
(3)根据注入类型(byName/byType)提取依赖的bean,并统一存入PropertyValues中
(4)应用InstantiationAwareBeanPostProcessor的postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)方法,对属性获取完毕填充前的再次处理,典型的应用是RequiredAnnotationBeanPostProcesser类中对属性的验证
(5)将所有的PropertyValues中的属性填充至BeanWrapper中
上面步骤中有几个地方是我们比较感兴趣的,它们分别是依赖注入(autowireByName/autowireByType)以及属性填充,接下来进一步分析这几个功能的实现细节

4.1 autowireByName

上面提到根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues中,我们看下byName是如何实现的:

/** 
     * 在传入的参数bw中,找出已经加载的bean,并递归实例化,进而加入到pvs中。 
     */  
    protected void autowireByName(  
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {  
        //寻找bw中需要依赖注入的属性  
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);  
        for (String propertyName : propertyNames) {  
            if (containsBean(propertyName)) {  
                //递归初始化相关的bean  
                Object bean = getBean(propertyName);  
                pvs.add(propertyName, bean);  
                //注册依赖  
                registerDependentBean(propertyName, beanName);  
                if (logger.isDebugEnabled()) {  
                    logger.debug("Added autowiring by name from bean name '" + beanName +  
                            "' via property '" + propertyName + "' to bean named '" + propertyName + "'");  
                }  
            }  
            else {  
                if (logger.isTraceEnabled()) {  
                    logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +  
                            "' by name: no matching bean found");  
                }  
            }  
        }  
    }  

此函数的功能就是根据传入的参数中的pvs中找出已经加载的bean,并递归实例化,然后加入到pvs中

4.2 autowireByType

autowireByType与autowireByName对于我们理解与使用来说复杂程度相似,但是实现功能的复杂度却不一样,我们看下方法代码:

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

        TypeConverter converter = getCustomTypeConverter();  
        if (converter == null) {  
            converter = bw;  
        }  

        Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);  
        //寻找bw中需要依赖注入的属性  
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);  
        for (String propertyName : propertyNames) {  
            try {  
                PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);  
                // Don't try autowiring by type for type Object: never makes sense,  
                // even if it technically is a unsatisfied, non-simple property.  
                if (!Object.class.equals(pd.getPropertyType())) {  
                    //探测指定属性的set方法  
                    MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);  
                    // Do not allow eager init for type matching in case of a prioritized post-processor.  
                    boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());  
                    DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);  
                    //解析指定beanName的属性所匹配的值,并把解析到的属性名称存储在autowiredBeanNames中,  
                    Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);  
                    if (autowiredArgument != null) {  
                        pvs.add(propertyName, autowiredArgument);  
                    }  
                    for (String autowiredBeanName : autowiredBeanNames) {  
                        //注册依赖  
                        registerDependentBean(autowiredBeanName, beanName);  
                        if (logger.isDebugEnabled()) {  
                            logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +  
                                    propertyName + "' to bean named '" + autowiredBeanName + "'");  
                        }  
                    }  
                    autowiredBeanNames.clear();  
                }  
            }  
            catch (BeansException ex) {  
                throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);  
            }  
        }  
    }  

根据名称第一步与根据属性第一步都是寻找bw中需要依赖注入的属性,然后遍历这些属性并寻找类型匹配的bean,其中最复杂就是寻找类型匹配的bean。spring中提供了对集合的类型注入支持,如使用如下注解方式:

@Autowired
private List<Test> tests;

这种方式spring会把所有与Test匹配的类型找出来并注入到tests属性中,正是由于这一因素,所以在autowireByType函数,新建了局部遍历autowireBeanNames,用于存储所有依赖的bean,如果只是对非集合类的属性注入来说,此属性并无用处。
对于寻找类型匹配的逻辑实现是封装在了resolveDependency函数中,其实现如下:

public Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
    descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());  
    if (descriptor.getDependencyType().equals(ObjectFactory.class)) {  
        //ObjectFactory类注入的特殊处理  
        return new DependencyObjectFactory(descriptor, beanName);  
    }  
    else if (descriptor.getDependencyType().equals(javaxInjectProviderClass)) {  
        //javaxInjectProviderClass类注入的特殊处理  
        return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName);  
    }  
    else {  
        //通用处理逻辑  
        return doResolveDependency(descriptor, descriptor.getDependencyType(), beanName, autowiredBeanNames, typeConverter);  
    }  
}  

protected Object doResolveDependency(DependencyDescriptor descriptor, Class<?> type, String beanName,  
        Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {  
    /* 
     * 用于支持Spring中新增的注解@Value 
     */  
    Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);  
    if (value != null) {  
        if (value instanceof String) {  
            String strVal = resolveEmbeddedValue((String) value);  
            BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);  
            value = evaluateBeanDefinitionString(strVal, bd);  
        }  
        TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());  
        return (descriptor.getField() != null ?  
                converter.convertIfNecessary(value, type, descriptor.getField()) :  
                converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));  
    }  
    //如果解析器没有成功解析,则需要考虑各种情况  
    //属性是数组类型  
    if (type.isArray()) {  
        Class<?> componentType = type.getComponentType();  
        //根据属性类型找到beanFactory中所有类型的匹配bean,  
        //返回值的构成为:key=匹配的beanName,value=beanName对应的实例化后的bean(通过getBean(beanName)返回)  
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, descriptor);  
        if (matchingBeans.isEmpty()) {  
            //如果autowire的require属性为true而找到的匹配项却为空则只能抛出异常  
            if (descriptor.isRequired()) {  
                raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor);  
            }  
            return null;  
        }  
        if (autowiredBeanNames != null) {  
            autowiredBeanNames.addAll(matchingBeans.keySet());  
        }  
        TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());  
        //通过转换器将bean的值转换为对应的type类型  
        return converter.convertIfNecessary(matchingBeans.values(), type);  
    }  
    //属性是Collection类型  
    else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {  
        Class<?> elementType = descriptor.getCollectionType();  
        if (elementType == null) {  
            if (descriptor.isRequired()) {  
                throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]");  
            }  
            return null;  
        }  
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, descriptor);  
        if (matchingBeans.isEmpty()) {  
            if (descriptor.isRequired()) {  
                raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor);  
            }  
            return null;  
        }  
        if (autowiredBeanNames != null) {  
            autowiredBeanNames.addAll(matchingBeans.keySet());  
        }  
        TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());  
        return converter.convertIfNecessary(matchingBeans.values(), type);  
    }  
    //属性是Map类型  
    else if (Map.class.isAssignableFrom(type) && type.isInterface()) {  
        Class<?> keyType = descriptor.getMapKeyType();  
        if (keyType == null || !String.class.isAssignableFrom(keyType)) {  
            if (descriptor.isRequired()) {  
                throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +  
                        "] must be assignable to [java.lang.String]");  
            }  
            return null;  
        }  
        Class<?> valueType = descriptor.getMapValueType();  
        if (valueType == null) {  
            if (descriptor.isRequired()) {  
                throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");  
            }  
            return null;  
        }  
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, descriptor);  
        if (matchingBeans.isEmpty()) {  
            if (descriptor.isRequired()) {  
                raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);  
            }  
            return null;  
        }  
        if (autowiredBeanNames != null) {  
            autowiredBeanNames.addAll(matchingBeans.keySet());  
        }  
        return matchingBeans;  
    }  
    else {  
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);  
        if (matchingBeans.isEmpty()) {  
            if (descriptor.isRequired()) {  
                raiseNoSuchBeanDefinitionException(type, "", descriptor);  
            }  
            return null;  
        }  
        if (matchingBeans.size() > 1) {  
            String primaryBeanName = determinePrimaryCandidate(matchingBeans, descriptor);  
            if (primaryBeanName == null) {  
                throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());  
            }  
            if (autowiredBeanNames != null) {  
                autowiredBeanNames.add(primaryBeanName);  
            }  
            return matchingBeans.get(primaryBeanName);  
        }  
        // We have exactly one match.  
        Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();  
        if (autowiredBeanNames != null) {  
            autowiredBeanNames.add(entry.getKey());  
        }  
        //已经确定只有一个匹配项  
        return entry.getValue();  
    }  
}  

寻找类型的匹配执行顺序时,首先尝试使用解析器解析,如果解析器没有成功解析,可能是默认的解析器没有做任何处理,或者是使用了自定义解析器。
虽说对于不同类型的处理方式不一致,但是大致的思路还是相似的,所以函数中只对数组类型进行了详细地注释。

4.3 applyPropertyValues

程序运行到这里,已经完成了对所有注入属性的获取,但是获取的属性是以PropertyValues形式存在的,还并没有应用到已经实例化的bean中,这一工作是在applyPropertyValues中。继续跟踪到方法体中:

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {  
        if (pvs == null || pvs.isEmpty()) {  
            return;  
        }  

        MutablePropertyValues mpvs = null;  
        List<PropertyValue> original;  

        if (System.getSecurityManager() != null) {  
            if (bw instanceof BeanWrapperImpl) {  
                ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());  
            }  
        }  

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

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

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

        // Set our (possibly massaged) deep copy.  
        try {  
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));  
        }  
        catch (BeansException ex) {  
            throw new BeanCreationException(  
                    mbd.getResourceDescription(), beanName, "Error setting property values", ex);  
        }  
    }  

5. 初始化bean

我们知道Spring在配置bean的时候有一个init-method属性,这个属性的作用是在bean实例化前调用init-method指定的方法来根据用户业务进行相应的实例化,首先看下这个方法的执行位置,Spring中程序已经执行过bean的实例化,并进行了属性填充,而就在这时将会调用用户设定的初始化方法。我回到之前的doCreateBean方法中,如下截图;
这里写图片描述
在populateBean方法下面有一个initializeBean(beanName, exposedObject, mbd)方法,这个就是用来执行用户设定的初始化操作。我们看下方法体:

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

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

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

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

虽说此函数的目的是进行客户设定的初始化方法的调用,但是除此之外还有其它一些必要的工作。
1.激Aware方法
我们先了解一下Aware方法的使用。Spring中提供了一些Aware接口,比如BeanFactoryAware,ApplicationContextAware,ResourceLoaderAware,ServletContextAware等,实现这些Aware接口的bean在被初始化后,可以取得一些相对应的资源,例如实现BeanFactoryAware的bean在初始化之后,Spring容器将会注入BeanFactory实例,而实现ApplicationContextAware的bean,在bean被初始化后,将会被注入ApplicationContext实例等。我们先通过示例方法了解下Aware的使用。
(1)定义普通bean,如下代码:

public class HelloBean {
    public void say()
    {
        System.out.println("Hello");
    }
}

(2)定义beanFactoryAware类型的bean

public class MyBeanAware implements BeanFactoryAware {
    private BeanFactory beanFactory;
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
    public void testAware()
    {
        //通过hello这个bean id从beanFactory获取实例  
        HelloBean hello = (HelloBean)beanFactory.getBean("hello");
        hello.say();
    }
}

(3)进行测试

public class Test {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        MyBeanAware test = (MyBeanAware)ctx.getBean("myBeanAware");
        test.testAware();
    }
}
其中applicationContext.xml文件内容
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="myBeanAware" class="com.yhl.myspring.demo.aware.MyBeanAware">
    </bean>
    <bean id="hello" class="com.yhl.myspring.demo.aware.HelloBean">
    </bean>
</beans>

上面的方法我们获取到Spring中BeanFactory,并且可以根据BeanFactory获取所有的bean,以及进行相关设置。还有其他Aware的使用都是大同小异,看一下Spring的实现方式:

private void invokeAwareMethods(final String beanName, final Object bean) {  
        if (bean instanceof Aware) {  
            if (bean instanceof BeanNameAware) {  
                ((BeanNameAware) bean).setBeanName(beanName);  
            }  
            if (bean instanceof BeanClassLoaderAware) {  
                ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());  
            }  
            if (bean instanceof BeanFactoryAware) {  
                ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);  
            }  
        }  

2.处理器的应用
BeanPostPrecessor我们经常看到Spring中使用,这是Spring开放式架构的一个必不可少的亮点,给用户充足的权限去更改或者扩展Spring,而除了BeanPostProcessor外还有很多其他的PostProcessor,当然大部分都以此为基础,集成自BeanPostProcessor。BeanPostProcessor在调用用户自定义初始化方法前或者调用自定义初始化方法后分别会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterinitialization方法,使用户可以根据自己的业务需求就行相应的处理。

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

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

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

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

3.激活自定义的init方法
客户定制的初始化方法除了我们熟知的使用配置init-method外,还有使自定义的bean实现InitializingBean接口,并在afterPropertiesSet中实现自己的初始化业务逻辑。
init-method与afterPropertiesSet都是在初始化bean时执行,执行顺序是afterPropertiesSet先执行,而init-method后执行。
在invokeInitMethods方法中就实现了这两个步骤的初始化调用。

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

        boolean isInitializingBean = (bean instanceof InitializingBean);  
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {  
            if (logger.isDebugEnabled()) {  
                logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");  
            }  
            if (System.getSecurityManager() != null) {  
                try {  
                    AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {  
                        public Object run() throws Exception {  
                            ((InitializingBean) bean).afterPropertiesSet();  
                            return null;  
                        }  
                    }, getAccessControlContext());  
                }  
                catch (PrivilegedActionException pae) {  
                    throw pae.getException();  
                }  
            }  
            else {  
                //属性初始化后的处理  
                ((InitializingBean) bean).afterPropertiesSet();  
            }  
        }  

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

6. 注册DisposableBean

Spring中不仅提供了对于初始化方法的扩展入口,同样也提供了销毁方法的扩展入口,对于销毁方法的扩展,除了配置属性destroy-method方法外,还可以注册后处理器DestructionAwareBeanPostProcessor来统一处理bean的销毁方法,代码:

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {  
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);  
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {  
        if (mbd.isSingleton()) {  
            // Register a DisposableBean implementation that performs all destruction  
            // work for the given bean: DestructionAwareBeanPostProcessors,  
            // DisposableBean interface, custom destroy method.  
            registerDisposableBean(beanName,  
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));  
        }  
        else {  
            // A bean with a custom scope...  
            Scope scope = this.scopes.get(mbd.getScope());  
            if (scope == null) {  
                throw new IllegalStateException("No Scope registered for scope '" + mbd.getScope() + "'");  
            }  
            scope.registerDestructionCallback(beanName,  
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));  
        }  
    }  
}  
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值