Spring源码解析Bean的实例化和依赖注入

Posted 行路难

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring源码解析Bean的实例化和依赖注入相关的知识,希望对你有一定的参考价值。

我们虽然获得了Bean的描述信息BeanDefinition,但是什么时候才会真正的实例化这些Bean呢。其实一共有两个触发点,但是最后实际上调用的是同一个方法。

第一个:在AbstractApplicationContext的refresh()方法中,容器会初始化lazy-init=false的bean。

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

第二个:在获得了ApplicationContext后,调用getBean(XX)方法。

实际上它们最终都是调用的AbstractBeanFactory的doGetBean(XX)方法。

/**
     * Return an instance, which may be shared or independent, of the specified bean.
     * @param name the name of the bean to retrieve
     * @param requiredType the required type of the bean to retrieve
     * @param args arguments to use if creating a prototype using explicit arguments to a
     * static factory method. It is invalid to use a non-null args value in any other case.
     * @param typeCheckOnly whether the instance is obtained for a type check,
     * not for actual use
     * @return an instance of the bean
     * @throws BeansException if the bean could not be created
     */
    @SuppressWarnings("unchecked")
    protected <T> T doGetBean(
            final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
            throws BeansException {
        //如果name已&开头,去掉&
        final String beanName = transformedBeanName(name);
        Object bean;

        // Eagerly check singleton cache for manually registered singletons.
        /**1.先在单例缓存中查找*/
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean \'" + beanName +
                            "\' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.debug("Returning cached instance of singleton bean \'" + beanName + "\'");
                }
            }
            /**2.判断返回instance本身还是要返回FacotryBean*/
            bean = 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 (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }
            //标记bean已被创建
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                // Guarantee initialization of beans that the current bean depends on.
                /**3.如果bean依赖于其他bean先初始化,先初始化依赖的bean*/
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dependsOnBean : dependsOn) {
                        getBean(dependsOnBean);
                        /**4.记录两个bean相互依赖关系,被依赖的bean在销毁前,要先要销毁依赖它的bean*/
                        registerDependentBean(dependsOnBean, beanName);
                    }
                }

                // Create bean instance.
                /**
                 * 5.创建单例bean,scope="singleton"
                 */
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                        public Object getObject() throws BeansException {
                            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;
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                /**
                 * 6.创建原型bean,scope="prototype"
                 */
                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);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }
                /**
                 * 7. scope=request/session/globalSession
                 */
                else {
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope \'" + scopeName + "\'");
                    }
                    try {
                        Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                            public Object getObject() throws BeansException {
                                beforePrototypeCreation(beanName);
                                try {
                                    return createBean(beanName, mbd, args);
                                }
                                finally {
                                    afterPrototypeCreation(beanName);
                                }
                            }
                        });
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {
                        throw new BeanCreationException(beanName,
                                "Scope \'" + scopeName + "\' is not active for the current thread; " +
                                "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                                ex);
                    }
                }
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }

        // Check if required type matches the type of the actual bean instance.
        if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
            try {
                return getTypeConverter().convertIfNecessary(bean, requiredType);
            }
            catch (TypeMismatchException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to convert bean \'" + name + "\' to required type [" +
                            ClassUtils.getQualifiedName(requiredType) + "]", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

AbstractAutowireCapableBeanFactory的createBean方法:

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

        if (logger.isDebugEnabled()) {
            logger.debug("Creating instance of bean \'" + beanName + "\'");
        }
        // Make sure bean class is actually resolved at this point.
        /**1.解析Bean的Class*/
        resolveBeanClass(mbd, beanName);

        // Prepare method overrides.
        try {
            /**2.方法注入准备*/
            mbd.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            /**3.BeanPostProcesser第一个扩展点,可以返回一个代理类*/
            Object bean = resolveBeforeInstantiation(beanName, mbd);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }
        /**4.执行spring创建bena实例的流程*/
        Object beanInstance = doCreateBean(beanName, mbd, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean \'" + beanName + "\'");
        }
        return beanInstance;
    }

 

 第4步才是真正创建实例和初始化的主要方法:

  1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
  2         // Instantiate the bean.
  3        
  4         BeanWrapper instanceWrapper = null;
  5         if (mbd.isSingleton()) {
  6             instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  7         }
  8         if (instanceWrapper == null) {
  9             /**5.创建bean实例*/
 10             instanceWrapper = createBeanInstance(beanName, mbd, args);
 11         }
 12         final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
 13         Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
 14 
 15         // Allow post-processors to modify the merged bean definition.
 16         /**
 17          * 6.MergedBeanDefinitionPostProcessor合并父子类属性,例如:List属性
 18          */
 19         synchronized (mbd.postProcessingLock) {
 20             if (!mbd.postProcessed) {
 21                 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
 22                 mbd.postProcessed = true;
 23             }
 24         }
 25 
 26         // Eagerly cache singletons to be able to resolve circular references
 27         // even when triggered by lifecycle interfaces like BeanFactoryAware.
 28         /**
 29          * 7.及早暴露单例bean引用,解决循环引用
 30          */
 31         boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
 32                 isSingletonCurrentlyInCreation(beanName));
 33         if (earlySingletonExposure) {
 34             if (logger.isDebugEnabled()) {
 35                 logger.debug("Eagerly caching bean \'" + beanName +
 36                         "\' to allow for resolving potential circular references");
 37             }
 38             //创建匿名内部类,匿名内部类会讲beanName、mbd,bean(final修饰)拷贝一份到内部类,已保证当前方法执行完成后局部变量退栈后内部类还可以访问。
 39             addSingletonFactory(beanName, new ObjectFactory<Object>() {
 40                 public Object getObject() throws BeansException {
 41                     return getEarlyBeanReference(beanName, mbd, bean);
 42                 }
 43             });
 44         }
 45 
 46         // Initialize the bean instance.
 47         Object exposedObject = bean;
 48         try {
 49             /**
 50              * 8.依赖注入
 51              */
 52             populateBean(beanName, mbd, instanceWrapper);
 53             if (exposedObject != null) {
 54                 /**
 55                  * 9.执行自定义BeanProcesser和init-method
 56                  */
 57                 exposedObject = initializeBean(beanName, exposedObject, mbd);
 58             }
 59         }
 60         catch (Throwable ex) {
 61             if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
 62                 throw (BeanCreationException) ex;
 63             }
 64             else {
 65                 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
 66             }
 67         }
 68 
 69         if (earlySingletonExposure) {
 70             Object earlySingletonReference = getSingleton(beanName, false);
 71             if (earlySingletonReference != null) {
 72                 if (exposedObject == bean) {
 73                     exposedObject = earlySingletonReference;
 74                 }
 75                 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
 76                     String[] dependentBeans = getDependentBeans(beanName);
 77                     Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
 78                     for (String dependentBean : dependentBeans) {
 79                         if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
 80                             actualDependentBeans.add(dependentBean);
 81                         }
 82                     }
 83                     if (!actualDependentBeans.isEmpty()) {
 84                         throw new BeanCurrentlyInCreationException(beanName,
 85                                 "Bean with name \'" + beanName + "\' has been injected into other beans [" +
 86                                 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
 87                                 "] in its raw version as part of a circular reference, but has eventually been " +
 88                                 "wrapped. This means that said other beans do not use the final version of the " +
 89                                 "bean. This is often the result of over-eager type matching - consider using " +
 90                                 "\'getBeanNamesOfType\' with the \'allowEagerInit\' flag turned off, for example.");
 91                     }
 92                 }
 93             }
 94         }
 95 
 96         // Register bean as disposable.
 97         try {
 98             /**
 99              * 10.注册DestructionAwareBeanPostProcessors和destroy-method
100              */
101             registerDisposableBeanIfNecessary(beanName, bean, mbd);
102         }
103         catch (BeanDefinitionValidationException ex) {
104             throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
105         }
106 
107         return exposedObject;
108     }

 

第5步:实例化Bean对象,封装成BeanWrapper

 1 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
 2         // Make sure bean class is actually resolved at this point.
 3         Class<?> beanClass = resolveBeanClass(mbd, beanName);
 4 
 5         if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
 6             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 7                     "Bean class isn\'t public, and non-public access not allowed: " + beanClass.getName());
 8         }
 9         /**5.1 通过静态方法来实例化bean*/
10         if (mbd.getFactoryMethodName() != null)  {
11             return instantiateUsingFactoryMethod(beanName, mbd, args);
12         }
13 
14         // Shortcut when re-creating the same bean...
15         boolean resolved = false;
16         boolean autowireNecessary = false;
17         if (args == null) {
18             synchronized (mbd.constructorArgumentLock) {
19                 if (mbd.resolvedConstructorOrFactoryMethod != null) {
20                     resolved = true;
21                     autowireNecessary = mbd.constructorArgumentsResolved;
22                 }
23             }
24         }
25         /**5.2 暂时不知道什么时候会走这???????*/
26         if (resolved) {
27             if (autowireNecessary) {
28                 return autowireConstructor(beanName, mbd, null, null);
29             }
30             else {
31                 return instantiateBean(beanName, mbd);
32             }
33         }
34 
35         // Need to determine the constructor...
36         /**5.3 BeanPostProcessor的又一个扩展点:SmartInstantiationAwareBeanPostProcessor。
37          *  检测Bean的构造器,可以检测出多个候选构造器,再有相应的策略决定使用哪一个,
38          *  如AutowiredAnnotationBeanPostProcessor实现将自动扫描通过@Autowired/@Va
39          */
40         Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
41         /**5.4 通过构造器实例化bean,包括autowire=constructor 和<constructor-arg></constructor-arg>*/
42         if (ctors != null ||
43                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
44                 mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
45             return autowireConstructor(beanName, mbd, ctors, args);
46         }
47 
48         // No special handling: simply use no-arg constructor.
49         /**5.5 通过无参构造器实例化bean*/
50         return instantiateBean(beanName, mbd);
51     }

 

第8步:Bean实例的初始化也就是属性的注入

 1     /**
 2      * Populate the bean instance in the given BeanWrapper with the property values
 3      * from the bean definition.
 4      * @param beanName the name of the bean
 5      * @param mbd the bean definition for the bean
 6      * @param bw BeanWrapper with bean instance
 7      */
 8     protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
 9         PropertyValues pvs = mbd.getPropertyValues();
10 
11         if (bw == null) {
12             if (!pvs.isEmpty()) {
13                 throw new BeanCreationException(
14                         mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
15             }
16             else {
17                 // Skip property population phase for null instance.
18                 return;
19             }
20         }
21 
22         // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
23         // state of the bean before properties are set. This can be used, for example,
24         // to support styles of field injection.
25         boolean continueWithPropertyPopulation = true;
26         /**
27          * 扩展点3:通过InstantiationAwareBeanPostProcessor给属性赋值
28          */
29         if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
30             for (BeanPostProcessor bp : getBeanPostProcessors()) {
31                 if (bp instanceof InstantiationAwareBeanPostProcessor) {
32                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
33                     if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
34                         continueWithPropertyPopulation = false;
35                         break;
36                     }
37                 }
38             }
39         }
40 
41         if (!continueWithPropertyPopulation) {
42             return;
43         }
44 
45         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
46                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
47             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
48 
49             // Add property values based on autowire by name if applicable.
50             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
51                 //根据Name自动装配
52                 autowireByName(beanName, mbd, bw, newPvs);
53             }
54 
55             // Add property values based on autowire by type if applicable.
56             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
57                 //根据Type自动装配
58                 autowireByType(beanName, mbd, bw, newPvs);
59             }
60 
61             pvs = newPvs;
62         }
63 
64         boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
65         boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
66 
67         if (hasInstAwareBpps || needsDepCheck) {
68             PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
69             if (hasInstAwareBpps) {
70                 /**
71                  * InstantiationAwareBeanPostProcesser在属性注入之前的扩展点
72                  */
73                 for (BeanPostProcessor bp : getBeanPostProcessors()) {
74                     if (bp instanceof InstantiationAwareBeanPostProcessor) {
75                         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
76                         pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
77                         if (pvs == null) {
78                             return;
79                         }
80                     }
81                 }
82             }
83             /**是否需要依赖检查*/
84             if (needsDepCheck) {
85                 checkDependencies(beanName, mbd, filteredPds, pvs);
以上是关于Spring源码解析Bean的实例化和依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

spring源码解析之IOC容器——依赖注入

Spring源码阅读Spring容器启动原理(下)-Bean实例的创建和依赖注入

面经三

Spring之BeanPostProcessor(后置处理器)介绍

Spring源码分析-bean创建(循环依赖)

Spring源码分析-bean创建(循环依赖)