zoukankan      html  css  js  c++  java
  • IOC容器的初始化过程

    1.ClassPathXmlApplicationContext类体系结构

                             

                         左边的黄色部分是ApplicationContext体系继承结构,右边是BeanFactory结构体系,两个体系是典型的模板方法设计模式的使用。

                         从该继承体系可以看出:

                        (1)BeanFactory是一个bean工厂的最基本定义,里面包含了一个bean工厂的几个最基本方法:getBean(),containsBean()等,是一个很纯粹的bean工厂,不关注资源、资源位置、事件等。

                                                             

                                 ApplicationContext是一个容器的最基本接口定义,它继承了BeanFactory,拥有工厂的基本方法。同时继承了ApplicationEventPublisher、MessageSource、ResourcePatternResolver等接口,使其定义了一些额外的功能,如事件、资源等这些额外功能。

     

    [java] view plain copy
     
    1. public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,  
    2.         MessageSource, ApplicationEventPublisher, ResourcePatternResolver   
    [java] view plain copy
     
    1. public interface HierarchicalBeanFactory extends BeanFactory   

     

                        (2)AbstractBeanFactory和AbstractAutowireCapableBeanFactory是两个模板抽象工厂类。AbstractBeanFactory提供了bean工厂的抽象基类,同时提供了ConfigurableBeanFactory的完整实现。AbstractAutowireapableBeanFactory是继承了AbstractBeanFactory的抽象工厂,里面提供了bean创建的支持,包括bean的创建、依赖注入、检查等功能,是一个核心的bean工厂类。

                        (3)ClassPathXmlApplicationContext之所以拥有bean工厂的功能是通过持有一个真正的bean工厂DefaultListableBeanFactory的实例,并通过代理该工厂完成

     

    [java] view plain copy
     
    1. public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext  
    [java] view plain copy
     
    1. public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext  
    [java] view plain copy
     
    1. public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext  
    2.         implements BeanNameAware, InitializingBean   
    [java] view plain copy
     
    1. public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {  
    2.         .........  
    3.     /** Bean factory for this context */  
    4.     private DefaultListableBeanFactory beanFactory;  

     

                        (4)ClassPathXmlApplicationContext的初始化过程是对本身容器的初始化,同时也是对其持有的DefaultListableBeanFactory的初始化

     

    2.容器初始化过程

                   整个过程可以通过下图来表示

                   

                       从xml文件到BeanDefinition的过程是ApplicationContext的职责范围,从BeanDefinition Map到Bean是BeanFactory的职责。可以看出ApplicationContext是一个运行时的容器需要提供不同资源的支持,屏蔽不同环境的差异化。而BeanDefinition是内部关于bean定义的基本结构,bean的创建就是基于它。

                      整个容器的初始化是通过调用refresh()方法来实现的,该方法定义在AbstractApplicationContext接口中。AbstractApplicationContext是容器的最基础的一个抽象父类。也就是说在里面定义了一个容器初始化的基本流程。

     

    [java] view plain copy
     
    1. public void refresh() throws BeansException, IllegalStateException {  
    2.     synchronized (this.startupShutdownMonitor) {  
    3.         // Prepare this context for refreshing.  
    4.         prepareRefresh();  
    5.   
    6.         // Tell the subclass to refresh the internal bean factory.  
    7.         ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  
    8.   
    9.         // Prepare the bean factory for use in this context.  
    10.         prepareBeanFactory(beanFactory);  
    11.   
    12.         try {  
    13.             // Allows post-processing of the bean factory in context subclasses.  
    14.             postProcessBeanFactory(beanFactory);  
    15.   
    16.             // Invoke factory processors registered as beans in the context.  
    17.             invokeBeanFactoryPostProcessors(beanFactory);  
    18.   
    19.             // Register bean processors that intercept bean creation.  
    20.             registerBeanPostProcessors(beanFactory);  
    21.   
    22.             // Initialize message source for this context.  
    23.             initMessageSource();  
    24.   
    25.             // Initialize event multicaster for this context.  
    26.             initApplicationEventMulticaster();  
    27.   
    28.             // Initialize other special beans in specific context subclasses.  
    29.             onRefresh();  
    30.   
    31.             // Check for listener beans and register them.  
    32.             registerListeners();  
    33.   
    34.             // Instantiate all remaining (non-lazy-init) singletons.  
    35.             finishBeanFactoryInitialization(beanFactory);  
    36.   
    37.             // Last step: publish corresponding event.  
    38.             finishRefresh();  
    39.         }  
    40.   
    41.         catch (BeansException ex) {  
    42.             logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);  
    43.   
    44.             // Destroy already created singletons to avoid dangling resources.  
    45.             destroyBeans();  
    46.   
    47.             // Reset 'active' flag.  
    48.             cancelRefresh(ex);  
    49.   
    50.             // Propagate exception to caller.  
    51.             throw ex;  
    52.         }  
    53.     }  
    54. }  

                   解释如下:

     

     

    3.Bean的创建过程

                   Bean的创建过程是BeanFactory索要完成的事情

                  (1)先看一下BeanDefinition的定义

                                        

                         从接口定义可以看出,通过bean定义能够bean的详细信息,如类名称、工厂类名称、scope、是否单例、是否抽象、是否延迟加载等等。

                   (2)bean的创建时机

                                 容器初始化的时候,会先对单例和非延迟加载的对象进行预先初始化。其他的都是延迟加载,是在第一次调用getBean的时候被创建。从DefaultListableBeanFactory的preInstantiateSingletons()里可以看到这样的实现规则

     

    [java] view plain copy
     
    1. public void preInstantiateSingletons() throws BeansException   
    2. {  
    3.     if (this.logger.isInfoEnabled())   
    4.     {  
    5.         this.logger.info("Pre-instantiating singletons in " + this);  
    6.     }  
    7.   
    8.     List<String> beanNames;  
    9.     synchronized (this.beanDefinitionMap)   
    10.     {  
    11.         // Iterate over a copy to allow for init methods which in turn register new bean definitions.  
    12.         // While this may not be part of the regular factory bootstrap, it does otherwise work fine.  
    13.         beanNames = new ArrayList<String>(this.beanDefinitionNames);  
    14.     }  
    15.   
    16.     // Trigger initialization of all non-lazy singleton beans...  
    17.     for (String beanName : beanNames)   
    18.     {  
    19.         RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);  
    20.         if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) //对非抽象、单例、非延迟加载的对象先实例化  
    21.         {  
    22.             if (isFactoryBean(beanName))   
    23.             {  
    24.                 final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);  
    25.                 boolean isEagerInit;  
    26.                 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean)   
    27.                 {  
    28.                     isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {  
    29.                         public Boolean run()   
    30.                         {  
    31.                             return ((SmartFactoryBean<?>) factory).isEagerInit();  
    32.                         }  
    33.                     }, getAccessControlContext());  
    34.                 }  
    35.                 else   
    36.                 {  
    37.                     isEagerInit = (factory instanceof SmartFactoryBean &&  
    38.                             ((SmartFactoryBean<?>) factory).isEagerInit());  
    39.                 }  
    40.                 if (isEagerInit)   
    41.                 {  
    42.                     getBean(beanName);  
    43.                 }  
    44.             }  
    45.             else  
    46.             {  
    47.                 getBean(beanName);  
    48.             }  
    49.         }  
    50.     }  
    51. }  

                    从上面的代码看,如果用以下配置,只有singletonBean会被预先创建

     

     

    [html] view plain copy
     
    1. <?xml version="1.0" encoding="GB2312"?>  
    2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">  
    3. <beans default-autowire="byName">  
    4.     <bean id="otherBean"          class="com.test.OtherBean" scope="prototype"/>  
    5.     <bean id="myBean"          class="com.test.MyBean" lazy-init="true"/>  
    6.     <bean id="singletonBean"          class="com.test.SingletonBean"/>  
    7. </beans>  



     

                   (3)bean的创建过程

                                 对于bean的创建过程,其实都是通过调用工厂的getBean方法来完成的。在这个方法中会完成对构造函数的选择、依赖注入等。

                                无论预先创建还是延迟加载都是调用getBean来实现,AbstractBeanFactory定义了getBean的过程:

     

    [java] view plain copy
     
    1. public Object getBean(String name) throws BeansException {  
    2.     return doGetBean(name, nullnullfalse);  
    3. }  

                                再看doGetBean()方法

     

     

    [java] view plain copy
     
    1. protected <T> T doGetBean(  
    2.         final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)  
    3.         throws BeansException   
    4.         {  
    5.   
    6.     final String beanName = transformedBeanName(name);  
    7.     Object bean;  
    8.   
    9.     // Eagerly check singleton cache for manually registered singletons.  
    10.     Object sharedInstance = getSingleton(beanName);  
    11.     if (sharedInstance != null && args == null)   
    12.     {  
    13.         if (logger.isDebugEnabled())   
    14.         {  
    15.             if (isSingletonCurrentlyInCreation(beanName))   
    16.             {  
    17.                 logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +  
    18.                         "' that is not fully initialized yet - a consequence of a circular reference");  
    19.             }  
    20.             else   
    21.             {  
    22.                 logger.debug("Returning cached instance of singleton bean '" + beanName + "'");  
    23.             }  
    24.         }  
    25.         bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  
    26.     }  
    27.   
    28.     else   
    29.     {  
    30.         // Fail if we're already creating this bean instance:  
    31.         // We're assumably within a circular reference.  
    32.         if (isPrototypeCurrentlyInCreation(beanName))   
    33.         {  
    34.             throw new BeanCurrentlyInCreationException(beanName);  
    35.         }  
    36.   
    37.         // Check if bean definition exists in this factory.  
    38.         BeanFactory parentBeanFactory = getParentBeanFactory();  
    39.         if (parentBeanFactory != null && !containsBeanDefinition(beanName))   
    40.         {  
    41.             // Not found -> check parent.  
    42.             String nameToLookup = originalBeanName(name);  
    43.             if (args != null)   
    44.             {  
    45.                 // Delegation to parent with explicit args.  
    46.                 return (T) parentBeanFactory.getBean(nameToLookup, args);  
    47.             }  
    48.             else   
    49.             {  
    50.                 // No args -> delegate to standard getBean method.  
    51.                 return parentBeanFactory.getBean(nameToLookup, requiredType);  
    52.             }  
    53.         }  
    54.   
    55.         if (!typeCheckOnly)   
    56.         {  
    57.             markBeanAsCreated(beanName);  
    58.         }  
    59.   
    60.         try   
    61.         {  
    62.             final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);  
    63.             checkMergedBeanDefinition(mbd, beanName, args);  
    64.   
    65.             // Guarantee initialization of beans that the current bean depends on.  
    66.             String[] dependsOn = mbd.getDependsOn();  
    67.             if (dependsOn != null)   
    68.             {  
    69.                 for (String dependsOnBean : dependsOn)   
    70.                 {  
    71.                     getBean(dependsOnBean);  
    72.                     registerDependentBean(dependsOnBean, beanName);  
    73.                 }  
    74.             }  
    75.   
    76.             // Create bean instance.  
    77.             if (mbd.isSingleton())              //如果是单例,间接通过getSingleton方法来创建,里面会实现将单例对象缓存  
    78.             {  
    79.                 sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {  
    80.                     public Object getObject() throws BeansException   
    81.                     {  
    82.                         try  
    83.                         {  
    84.                             return createBean(beanName, mbd, args);  
    85.                         }  
    86.                         catch (BeansException ex)   
    87.                         {  
    88.                             // Explicitly remove instance from singleton cache: It might have been put there  
    89.                             // eagerly by the creation process, to allow for circular reference resolution.  
    90.                             // Also remove any beans that received a temporary reference to the bean.  
    91.                             destroySingleton(beanName);  
    92.                             throw ex;  
    93.                         }  
    94.                     }  
    95.                 });  
    96.                 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);  
    97.             }  
    98.   
    99.             else if (mbd.isPrototype())                 //非单例对象  
    100.             {  
    101.                 // It's a prototype -> create a new instance.  
    102.                 Object prototypeInstance = null;  
    103.                 try   
    104.                 {  
    105.                     beforePrototypeCreation(beanName);  
    106.                     prototypeInstance = createBean(beanName, mbd, args);  
    107.                 }  
    108.                 finally   
    109.                 {  
    110.                     afterPrototypeCreation(beanName);  
    111.                 }  
    112.                 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);  
    113.             }  
    114.   
    115.             else   
    116.             {  
    117.                 String scopeName = mbd.getScope();  
    118.                 final Scope scope = this.scopes.get(scopeName);  
    119.                 if (scope == null)   
    120.                 {  
    121.                     throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");  
    122.                 }  
    123.                 try   
    124.                 {  
    125.                     Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {  
    126.                         public Object getObject() throws BeansException   
    127.                         {  
    128.                             beforePrototypeCreation(beanName);  
    129.                             try   
    130.                             {  
    131.                                 return createBean(beanName, mbd, args);  
    132.                             }  
    133.                             finally   
    134.                             {  
    135.                                 afterPrototypeCreation(beanName);  
    136.                             }  
    137.                         }  
    138.                     });  
    139.                     bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);  
    140.                 }  
    141.                 catch (IllegalStateException ex)   
    142.                 {  
    143.                     throw new BeanCreationException(beanName,  
    144.                             "Scope '" + scopeName + "' is not active for the current thread; " +  
    145.                             "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",  
    146.                             ex);  
    147.                 }  
    148.             }  
    149.         }  
    150.         catch (BeansException ex)  
    151.         {  
    152.             cleanupAfterBeanCreationFailure(beanName);  
    153.             throw ex;  
    154.         }  
    155.     }  
    156.   
    157.     // Check if required type matches the type of the actual bean instance.  
    158.     if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass()))   
    159.     {  
    160.         try   
    161.         {  
    162.             return getTypeConverter().convertIfNecessary(bean, requiredType);  
    163.         }  
    164.         catch (TypeMismatchException ex)   
    165.         {  
    166.             if (logger.isDebugEnabled())   
    167.             {  
    168.                 logger.debug("Failed to convert bean '" + name + "' to required type [" +  
    169.                         ClassUtils.getQualifiedName(requiredType) + "]", ex);  
    170.             }  
    171.             throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());  
    172.         }  
    173.     }  
    174.     return (T) bean;  
    175. }  

                    doGetBean的大概过程

     

                    1)先试着从单例缓存中获取对象

                    2)从父容器中取定义,有则由父容器创建

                    3)如果是单例,则走单例对象的创建过程:在spring容器中单例对象和非单例对象的创建过程是一样的。都会调用父类AbstractAutowireCapableBeanFactory的createBean()方法。不同的是单例对象之创建一次并且需要缓存起来。DefaultListableBeanFactory的父类DefaultSingletonBeanRegistry提供了对单例对象缓存等支持工作。所以是单例对象的话,会调用DefaultSingletonBeanRegistry的getSingleton()方法,它会间接调用AbstractAutowireCapableBeanFactory的createBean()方法。
                         

                   bean的创建是由AbstractAutowireCapableBeanFactory来定义

     

    [java] view plain copy
     
    1. /** 
    2.  * Central method of this class: creates a bean instance, 
    3.  * populates the bean instance, applies post-processors, etc. 
    4.  * @see #doCreateBean 
    5.  */  
    6. @Override  
    7. protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)  
    8.         throws BeanCreationException   
    9.         {  
    10.   
    11.     if (logger.isDebugEnabled())  
    12.     {  
    13.         logger.debug("Creating instance of bean '" + beanName + "'");  
    14.     }  
    15.     // Make sure bean class is actually resolved at this point.  
    16.     resolveBeanClass(mbd, beanName);  
    17.   
    18.     // Prepare method overrides.  
    19.     try   
    20.     {  
    21.         mbd.prepareMethodOverrides();  
    22.     }  
    23.     catch (BeanDefinitionValidationException ex)   
    24.     {  
    25.         throw new BeanDefinitionStoreException(mbd.getResourceDescription(),  
    26.                 beanName, "Validation of method overrides failed", ex);  
    27.     }  
    28.   
    29.     try   
    30.     {  
    31.         // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.  
    32.         Object bean = resolveBeforeInstantiation(beanName, mbd);  
    33.         if (bean != null)   
    34.         {  
    35.             return bean;  
    36.         }  
    37.     }  
    38.     catch (Throwable ex)   
    39.     {  
    40.         throw new BeanCreationException(mbd.getResourceDescription(), beanName,  
    41.                 "BeanPostProcessor before instantiation of bean failed", ex);  
    42.     }  
    43.   
    44.     Object beanInstance = doCreateBean(beanName, mbd, args);  
    45.     if (logger.isDebugEnabled())   
    46.     {  
    47.         logger.debug("Finished creating instance of bean '" + beanName + "'");  
    48.     }  
    49.     return beanInstance;  
    50. }  

                    createBean会调用doCreateBean方法

     

     

    [java] view plain copy
     
    1. /** 
    2.  * Actually create the specified bean. Pre-creation processing has already happened 
    3.  * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. 
    4.  * <p>Differentiates between default bean instantiation, use of a 
    5.  * factory method, and autowiring a constructor. 
    6.  * @param beanName the name of the bean 
    7.  * @param mbd the merged bean definition for the bean 
    8.  * @param args arguments to use if creating a prototype using explicit arguments to a 
    9.  * static factory method. This parameter must be {@code null} except in this case. 
    10.  * @return a new instance of the bean 
    11.  * @throws BeanCreationException if the bean could not be created 
    12.  * @see #instantiateBean 
    13.  * @see #instantiateUsingFactoryMethod 
    14.  * @see #autowireConstructor 
    15.  */  
    16. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)   
    17. {  
    18.     // Instantiate the bean.  
    19.     BeanWrapper instanceWrapper = null;  
    20.     if (mbd.isSingleton())   
    21.     {  
    22.         instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);  
    23.     }  
    24.     if (instanceWrapper == null)   
    25.     {  
    26.         instanceWrapper = createBeanInstance(beanName, mbd, args);  
    27.     }  
    28.     final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);  
    29.     Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);  
    30.   
    31.     // Allow post-processors to modify the merged bean definition.  
    32.     synchronized (mbd.postProcessingLock)   
    33.     {  
    34.         if (!mbd.postProcessed)   
    35.         {  
    36.             applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);  
    37.             mbd.postProcessed = true;  
    38.         }  
    39.     }  
    40.   
    41.     // Eagerly cache singletons to be able to resolve circular references  
    42.     // even when triggered by lifecycle interfaces like BeanFactoryAware.  
    43.     boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&  
    44.             isSingletonCurrentlyInCreation(beanName));  
    45.     if (earlySingletonExposure)   
    46.     {  
    47.         if (logger.isDebugEnabled())   
    48.         {  
    49.             logger.debug("Eagerly caching bean '" + beanName +  
    50.                     "' to allow for resolving potential circular references");  
    51.         }  
    52.         addSingletonFactory(beanName, new ObjectFactory<Object>() {  
    53.             public Object getObject() throws BeansException   
    54.             {  
    55.                 return getEarlyBeanReference(beanName, mbd, bean);  
    56.             }  
    57.         });  
    58.     }  
    59.   
    60.     // Initialize the bean instance.  
    61.     Object exposedObject = bean;  
    62.     try   
    63.     {  
    64.         populateBean(beanName, mbd, instanceWrapper);  
    65.         if (exposedObject != null)   
    66.         {  
    67.             exposedObject = initializeBean(beanName, exposedObject, mbd);  
    68.         }  
    69.     }  
    70.     catch (Throwable ex)   
    71.     {  
    72.         if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName()))   
    73.         {  
    74.             throw (BeanCreationException) ex;  
    75.         }  
    76.         else   
    77.         {  
    78.             throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);  
    79.         }  
    80.     }  
    81.   
    82.     if (earlySingletonExposure)  
    83.     {  
    84.         Object earlySingletonReference = getSingleton(beanName, false);  
    85.         if (earlySingletonReference != null)   
    86.         {  
    87.             if (exposedObject == bean)   
    88.             {  
    89.                 exposedObject = earlySingletonReference;  
    90.             }  
    91.             else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName))   
    92.             {  
    93.                 String[] dependentBeans = getDependentBeans(beanName);  
    94.                 Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);  
    95.                 for (String dependentBean : dependentBeans)   
    96.                 {  
    97.                     if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean))   
    98.                     {  
    99.                         actualDependentBeans.add(dependentBean);  
    100.                     }  
    101.                 }  
    102.                 if (!actualDependentBeans.isEmpty())   
    103.                 {  
    104.                     throw new BeanCurrentlyInCreationException(beanName,  
    105.                             "Bean with name '" + beanName + "' has been injected into other beans [" +  
    106.                             StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +  
    107.                             "] in its raw version as part of a circular reference, but has eventually been " +  
    108.                             "wrapped. This means that said other beans do not use the final version of the " +  
    109.                             "bean. This is often the result of over-eager type matching - consider using " +  
    110.                             "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");  
    111.                 }  
    112.             }  
    113.         }  
    114.     }  
    115.   
    116.     // Register bean as disposable.  
    117.     try   
    118.     {  
    119.         registerDisposableBeanIfNecessary(beanName, bean, mbd);  
    120.     }  
    121.     catch (BeanDefinitionValidationException ex)   
    122.     {  
    123.         throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);  
    124.     }  
    125.   
    126.     return exposedObject;  
    127. }  

                    doCreateBean流程

     

                    1)会创建一个BeanWrapper对象,用来存放实例化对象

                    2)如果没有指定构造函数,会通过反射拿到一个默认的构造函数

                    3)调用spring的BeanUtils的instantiateClass方法,通过反射创建对象。

                    4)applyMergedBeanDefinitionPostProcessors

                    5)populateBean(),根据注入方式进行注入。根据是否有依赖检查进行依赖检查

                          执行bean注入的时候,会选择注入类型

     

    [java] view plain copy
     
    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. {  
    10.     PropertyValues pvs = mbd.getPropertyValues();  
    11.   
    12.     if (bw == null)   
    13.     {  
    14.         if (!pvs.isEmpty())   
    15.         {  
    16.             throw new BeanCreationException(  
    17.                     mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");  
    18.         }  
    19.         else   
    20.         {  
    21.             // Skip property population phase for null instance.  
    22.             return;  
    23.         }  
    24.     }  
    25.   
    26.     // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the  
    27.     // state of the bean before properties are set. This can be used, for example,  
    28.     // to support styles of field injection.  
    29.     boolean continueWithPropertyPopulation = true;  
    30.   
    31.     if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors())   
    32.     {  
    33.         for (BeanPostProcessor bp : getBeanPostProcessors())   
    34.         {  
    35.             if (bp instanceof InstantiationAwareBeanPostProcessor)   
    36.             {  
    37.                 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  
    38.                 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName))   
    39.                 {  
    40.                     continueWithPropertyPopulation = false;  
    41.                     break;  
    42.                 }  
    43.             }  
    44.         }  
    45.     }  
    46.   
    47.     if (!continueWithPropertyPopulation)   
    48.     {  
    49.         return;  
    50.     }  
    51.   
    52.     if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||  
    53.             mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE)   
    54.     {  
    55.         MutablePropertyValues newPvs = new MutablePropertyValues(pvs);  
    56.   
    57.         // Add property values based on autowire by name if applicable.  
    58.         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) //根据名称注入  
    59.         {  
    60.             autowireByName(beanName, mbd, bw, newPvs);  
    61.         }  
    62.   
    63.         // Add property values based on autowire by type if applicable.  
    64.         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) //根据类型注入  
    65.         {  
    66.             autowireByType(beanName, mbd, bw, newPvs);  
    67.         }  
    68.   
    69.         pvs = newPvs;  
    70.     }  
    71.   
    72.     boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();  
    73.     boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);  
    74.   
    75.     if (hasInstAwareBpps || needsDepCheck)   
    76.     {  
    77.         PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);  
    78.         if (hasInstAwareBpps)   
    79.         {  
    80.             for (BeanPostProcessor bp : getBeanPostProcessors())   
    81.             {  
    82.                 if (bp instanceof InstantiationAwareBeanPostProcessor)   
    83.                 {  
    84.                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  
    85.                     pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);  
    86.                     if (pvs == null)   
    87.                     {  
    88.                         return;  
    89.                     }  
    90.                 }  
    91.             }  
    92.         }  
    93.         if (needsDepCheck)   
    94.         {  
    95.             checkDependencies(beanName, mbd, filteredPds, pvs);  
    96.         }  
    97.     }  
    98.   
    99.     applyPropertyValues(beanName, mbd, bw, pvs);  
    100. }  

                  6)initializeBean(),判断是否实现了BeanNameAware、BeanClassLoaderAware等spring提供的接口,如果实现了,进行默认的注入。同时判断是否实现了InitializingBean接口,如果实现了,调用afterPropertySet方法

     

     

    [java] view plain copy
     
    1. protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {  
    2.     if (System.getSecurityManager() != null) {  
    3.         AccessController.doPrivileged(new PrivilegedAction<Object>() {  
    4.             public Object run() {  
    5.                 invokeAwareMethods(beanName, bean);  
    6.                 return null;  
    7.             }  
    8.         }, getAccessControlContext());  
    9.     }  
    10.     else {  
    11.         invokeAwareMethods(beanName, bean);  
    12.     }  
    13.   
    14.     Object wrappedBean = bean;  
    15.     if (mbd == null || !mbd.isSynthetic()) {  
    16.         wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);  
    17.     }  
    18.   
    19.     try {  
    20.         invokeInitMethods(beanName, wrappedBean, mbd);  
    21.     }  
    22.     catch (Throwable ex) {  
    23.         throw new BeanCreationException(  
    24.                 (mbd != null ? mbd.getResourceDescription() : null),  
    25.                 beanName, "Invocation of init method failed", ex);  
    26.     }  
    27.   
    28.     if (mbd == null || !mbd.isSynthetic()) {  
    29.         wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);  
    30.     }  
    31.     return wrappedBean;  
    32. }  
    33.   
    34. private void invokeAwareMethods(final String beanName, final Object bean) {  
    35.     if (bean instanceof Aware) {  
    36.         if (bean instanceof BeanNameAware) {  
    37.             ((BeanNameAware) bean).setBeanName(beanName);  
    38.         }  
    39.         if (bean instanceof BeanClassLoaderAware) {  
    40.             ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());  
    41.         }  
    42.         if (bean instanceof BeanFactoryAware) {  
    43.             ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);  
    44.         }  
    45.     }  
    46. }  

                    其中invokeInitMethods实现如下:

     

     

    [java] view plain copy
     
    1. protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)  
    2.         throws Throwable {  
    3.   
    4.     boolean isInitializingBean = (bean instanceof InitializingBean);  
    5.     if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {  
    6.         if (logger.isDebugEnabled()) {  
    7.             logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");  
    8.         }  
    9.         if (System.getSecurityManager() != null) {  
    10.             try {  
    11.                 AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {  
    12.                     public Object run() throws Exception {  
    13.                         ((InitializingBean) bean).afterPropertiesSet();  
    14.                         return null;  
    15.                     }  
    16.                 }, getAccessControlContext());  
    17.             }  
    18.             catch (PrivilegedActionException pae) {  
    19.                 throw pae.getException();  
    20.             }  
    21.         }  
    22.         else {  
    23.             ((InitializingBean) bean).afterPropertiesSet();  
    24.         }  
    25.     }  
    26.   
    27.     if (mbd != null) {  
    28.         String initMethodName = mbd.getInitMethodName();  
    29.         if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&  
    30.                 !mbd.isExternallyManagedInitMethod(initMethodName)) {  
    31.             invokeCustomInitMethod(beanName, bean, mbd);  
    32.         }  
    33.     }  
    34. }  

     

    Ioc容器初始化过程

    1.ClassPathXmlApplicationContext类体系结构

                             

                         左边的黄色部分是ApplicationContext体系继承结构,右边是BeanFactory结构体系,两个体系是典型的模板方法设计模式的使用。

                         从该继承体系可以看出:

                        (1)BeanFactory是一个bean工厂的最基本定义,里面包含了一个bean工厂的几个最基本方法:getBean(),containsBean()等,是一个很纯粹的bean工厂,不关注资源、资源位置、事件等。

                                                             

                                 ApplicationContext是一个容器的最基本接口定义,它继承了BeanFactory,拥有工厂的基本方法。同时继承了ApplicationEventPublisher、MessageSource、ResourcePatternResolver等接口,使其定义了一些额外的功能,如事件、资源等这些额外功能。

     

    [java] view plain copy
     
    1. public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,  
    2.         MessageSource, ApplicationEventPublisher, ResourcePatternResolver   
    [java] view plain copy
     
    1. public interface HierarchicalBeanFactory extends BeanFactory   

     

                        (2)AbstractBeanFactory和AbstractAutowireCapableBeanFactory是两个模板抽象工厂类。AbstractBeanFactory提供了bean工厂的抽象基类,同时提供了ConfigurableBeanFactory的完整实现。AbstractAutowireapableBeanFactory是继承了AbstractBeanFactory的抽象工厂,里面提供了bean创建的支持,包括bean的创建、依赖注入、检查等功能,是一个核心的bean工厂类。

                        (3)ClassPathXmlApplicationContext之所以拥有bean工厂的功能是通过持有一个真正的bean工厂DefaultListableBeanFactory的实例,并通过代理该工厂完成

     

    [java] view plain copy
     
    1. public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext  
    [java] view plain copy
     
    1. public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext  
    [java] view plain copy
     
    1. public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext  
    2.         implements BeanNameAware, InitializingBean   
    [java] view plain copy
     
    1. public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {  
    2.         .........  
    3.     /** Bean factory for this context */  
    4.     private DefaultListableBeanFactory beanFactory;  

     

                        (4)ClassPathXmlApplicationContext的初始化过程是对本身容器的初始化,同时也是对其持有的DefaultListableBeanFactory的初始化

     

    2.容器初始化过程

                   整个过程可以通过下图来表示

                   

                       从xml文件到BeanDefinition的过程是ApplicationContext的职责范围,从BeanDefinition Map到Bean是BeanFactory的职责。可以看出ApplicationContext是一个运行时的容器需要提供不同资源的支持,屏蔽不同环境的差异化。而BeanDefinition是内部关于bean定义的基本结构,bean的创建就是基于它。

                      整个容器的初始化是通过调用refresh()方法来实现的,该方法定义在AbstractApplicationContext接口中。AbstractApplicationContext是容器的最基础的一个抽象父类。也就是说在里面定义了一个容器初始化的基本流程。

     

    [java] view plain copy
     
    1. public void refresh() throws BeansException, IllegalStateException {  
    2.     synchronized (this.startupShutdownMonitor) {  
    3.         // Prepare this context for refreshing.  
    4.         prepareRefresh();  
    5.   
    6.         // Tell the subclass to refresh the internal bean factory.  
    7.         ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  
    8.   
    9.         // Prepare the bean factory for use in this context.  
    10.         prepareBeanFactory(beanFactory);  
    11.   
    12.         try {  
    13.             // Allows post-processing of the bean factory in context subclasses.  
    14.             postProcessBeanFactory(beanFactory);  
    15.   
    16.             // Invoke factory processors registered as beans in the context.  
    17.             invokeBeanFactoryPostProcessors(beanFactory);  
    18.   
    19.             // Register bean processors that intercept bean creation.  
    20.             registerBeanPostProcessors(beanFactory);  
    21.   
    22.             // Initialize message source for this context.  
    23.             initMessageSource();  
    24.   
    25.             // Initialize event multicaster for this context.  
    26.             initApplicationEventMulticaster();  
    27.   
    28.             // Initialize other special beans in specific context subclasses.  
    29.             onRefresh();  
    30.   
    31.             // Check for listener beans and register them.  
    32.             registerListeners();  
    33.   
    34.             // Instantiate all remaining (non-lazy-init) singletons.  
    35.             finishBeanFactoryInitialization(beanFactory);  
    36.   
    37.             // Last step: publish corresponding event.  
    38.             finishRefresh();  
    39.         }  
    40.   
    41.         catch (BeansException ex) {  
    42.             logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);  
    43.   
    44.             // Destroy already created singletons to avoid dangling resources.  
    45.             destroyBeans();  
    46.   
    47.             // Reset 'active' flag.  
    48.             cancelRefresh(ex);  
    49.   
    50.             // Propagate exception to caller.  
    51.             throw ex;  
    52.         }  
    53.     }  
    54. }  

                   解释如下:

     

     

    3.Bean的创建过程

                   Bean的创建过程是BeanFactory索要完成的事情

                  (1)先看一下BeanDefinition的定义

                                        

                         从接口定义可以看出,通过bean定义能够bean的详细信息,如类名称、工厂类名称、scope、是否单例、是否抽象、是否延迟加载等等。

                   (2)bean的创建时机

                                 容器初始化的时候,会先对单例和非延迟加载的对象进行预先初始化。其他的都是延迟加载,是在第一次调用getBean的时候被创建。从DefaultListableBeanFactory的preInstantiateSingletons()里可以看到这样的实现规则

     

    [java] view plain copy
     
    1. public void preInstantiateSingletons() throws BeansException   
    2. {  
    3.     if (this.logger.isInfoEnabled())   
    4.     {  
    5.         this.logger.info("Pre-instantiating singletons in " + this);  
    6.     }  
    7.   
    8.     List<String> beanNames;  
    9.     synchronized (this.beanDefinitionMap)   
    10.     {  
    11.         // Iterate over a copy to allow for init methods which in turn register new bean definitions.  
    12.         // While this may not be part of the regular factory bootstrap, it does otherwise work fine.  
    13.         beanNames = new ArrayList<String>(this.beanDefinitionNames);  
    14.     }  
    15.   
    16.     // Trigger initialization of all non-lazy singleton beans...  
    17.     for (String beanName : beanNames)   
    18.     {  
    19.         RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);  
    20.         if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) //对非抽象、单例、非延迟加载的对象先实例化  
    21.         {  
    22.             if (isFactoryBean(beanName))   
    23.             {  
    24.                 final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);  
    25.                 boolean isEagerInit;  
    26.                 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean)   
    27.                 {  
    28.                     isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {  
    29.                         public Boolean run()   
    30.                         {  
    31.                             return ((SmartFactoryBean<?>) factory).isEagerInit();  
    32.                         }  
    33.                     }, getAccessControlContext());  
    34.                 }  
    35.                 else   
    36.                 {  
    37.                     isEagerInit = (factory instanceof SmartFactoryBean &&  
    38.                             ((SmartFactoryBean<?>) factory).isEagerInit());  
    39.                 }  
    40.                 if (isEagerInit)   
    41.                 {  
    42.                     getBean(beanName);  
    43.                 }  
    44.             }  
    45.             else  
    46.             {  
    47.                 getBean(beanName);  
    48.             }  
    49.         }  
    50.     }  
    51. }  

                    从上面的代码看,如果用以下配置,只有singletonBean会被预先创建

     

     

    [html] view plain copy
     
    1. <?xml version="1.0" encoding="GB2312"?>  
    2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">  
    3. <beans default-autowire="byName">  
    4.     <bean id="otherBean"          class="com.test.OtherBean" scope="prototype"/>  
    5.     <bean id="myBean"          class="com.test.MyBean" lazy-init="true"/>  
    6.     <bean id="singletonBean"          class="com.test.SingletonBean"/>  
    7. </beans>  



     

                   (3)bean的创建过程

                                 对于bean的创建过程,其实都是通过调用工厂的getBean方法来完成的。在这个方法中会完成对构造函数的选择、依赖注入等。

                                无论预先创建还是延迟加载都是调用getBean来实现,AbstractBeanFactory定义了getBean的过程:

     

    [java] view plain copy
     
    1. public Object getBean(String name) throws BeansException {  
    2.     return doGetBean(name, nullnullfalse);  
    3. }  

                                再看doGetBean()方法

     

     

    [java] view plain copy
     
    1. protected <T> T doGetBean(  
    2.         final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)  
    3.         throws BeansException   
    4.         {  
    5.   
    6.     final String beanName = transformedBeanName(name);  
    7.     Object bean;  
    8.   
    9.     // Eagerly check singleton cache for manually registered singletons.  
    10.     Object sharedInstance = getSingleton(beanName);  
    11.     if (sharedInstance != null && args == null)   
    12.     {  
    13.         if (logger.isDebugEnabled())   
    14.         {  
    15.             if (isSingletonCurrentlyInCreation(beanName))   
    16.             {  
    17.                 logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +  
    18.                         "' that is not fully initialized yet - a consequence of a circular reference");  
    19.             }  
    20.             else   
    21.             {  
    22.                 logger.debug("Returning cached instance of singleton bean '" + beanName + "'");  
    23.             }  
    24.         }  
    25.         bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  
    26.     }  
    27.   
    28.     else   
    29.     {  
    30.         // Fail if we're already creating this bean instance:  
    31.         // We're assumably within a circular reference.  
    32.         if (isPrototypeCurrentlyInCreation(beanName))   
    33.         {  
    34.             throw new BeanCurrentlyInCreationException(beanName);  
    35.         }  
    36.   
    37.         // Check if bean definition exists in this factory.  
    38.         BeanFactory parentBeanFactory = getParentBeanFactory();  
    39.         if (parentBeanFactory != null && !containsBeanDefinition(beanName))   
    40.         {  
    41.             // Not found -> check parent.  
    42.             String nameToLookup = originalBeanName(name);  
    43.             if (args != null)   
    44.             {  
    45.                 // Delegation to parent with explicit args.  
    46.                 return (T) parentBeanFactory.getBean(nameToLookup, args);  
    47.             }  
    48.             else   
    49.             {  
    50.                 // No args -> delegate to standard getBean method.  
    51.                 return parentBeanFactory.getBean(nameToLookup, requiredType);  
    52.             }  
    53.         }  
    54.   
    55.         if (!typeCheckOnly)   
    56.         {  
    57.             markBeanAsCreated(beanName);  
    58.         }  
    59.   
    60.         try   
    61.         {  
    62.             final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);  
    63.             checkMergedBeanDefinition(mbd, beanName, args);  
    64.   
    65.             // Guarantee initialization of beans that the current bean depends on.  
    66.             String[] dependsOn = mbd.getDependsOn();  
    67.             if (dependsOn != null)   
    68.             {  
    69.                 for (String dependsOnBean : dependsOn)   
    70.                 {  
    71.                     getBean(dependsOnBean);  
    72.                     registerDependentBean(dependsOnBean, beanName);  
    73.                 }  
    74.             }  
    75.   
    76.             // Create bean instance.  
    77.             if (mbd.isSingleton())              //如果是单例,间接通过getSingleton方法来创建,里面会实现将单例对象缓存  
    78.             {  
    79.                 sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {  
    80.                     public Object getObject() throws BeansException   
    81.                     {  
    82.                         try  
    83.                         {  
    84.                             return createBean(beanName, mbd, args);  
    85.                         }  
    86.                         catch (BeansException ex)   
    87.                         {  
    88.                             // Explicitly remove instance from singleton cache: It might have been put there  
    89.                             // eagerly by the creation process, to allow for circular reference resolution.  
    90.                             // Also remove any beans that received a temporary reference to the bean.  
    91.                             destroySingleton(beanName);  
    92.                             throw ex;  
    93.                         }  
    94.                     }  
    95.                 });  
    96.                 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);  
    97.             }  
    98.   
    99.             else if (mbd.isPrototype())                 //非单例对象  
    100.             {  
    101.                 // It's a prototype -> create a new instance.  
    102.                 Object prototypeInstance = null;  
    103.                 try   
    104.                 {  
    105.                     beforePrototypeCreation(beanName);  
    106.                     prototypeInstance = createBean(beanName, mbd, args);  
    107.                 }  
    108.                 finally   
    109.                 {  
    110.                     afterPrototypeCreation(beanName);  
    111.                 }  
    112.                 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);  
    113.             }  
    114.   
    115.             else   
    116.             {  
    117.                 String scopeName = mbd.getScope();  
    118.                 final Scope scope = this.scopes.get(scopeName);  
    119.                 if (scope == null)   
    120.                 {  
    121.                     throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");  
    122.                 }  
    123.                 try   
    124.                 {  
    125.                     Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {  
    126.                         public Object getObject() throws BeansException   
    127.                         {  
    128.                             beforePrototypeCreation(beanName);  
    129.                             try   
    130.                             {  
    131.                                 return createBean(beanName, mbd, args);  
    132.                             }  
    133.                             finally   
    134.                             {  
    135.                                 afterPrototypeCreation(beanName);  
    136.                             }  
    137.                         }  
    138.                     });  
    139.                     bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);  
    140.                 }  
    141.                 catch (IllegalStateException ex)   
    142.                 {  
    143.                     throw new BeanCreationException(beanName,  
    144.                             "Scope '" + scopeName + "' is not active for the current thread; " +  
    145.                             "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",  
    146.                             ex);  
    147.                 }  
    148.             }  
    149.         }  
    150.         catch (BeansException ex)  
    151.         {  
    152.             cleanupAfterBeanCreationFailure(beanName);  
    153.             throw ex;  
    154.         }  
    155.     }  
    156.   
    157.     // Check if required type matches the type of the actual bean instance.  
    158.     if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass()))   
    159.     {  
    160.         try   
    161.         {  
    162.             return getTypeConverter().convertIfNecessary(bean, requiredType);  
    163.         }  
    164.         catch (TypeMismatchException ex)   
    165.         {  
    166.             if (logger.isDebugEnabled())   
    167.             {  
    168.                 logger.debug("Failed to convert bean '" + name + "' to required type [" +  
    169.                         ClassUtils.getQualifiedName(requiredType) + "]", ex);  
    170.             }  
    171.             throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());  
    172.         }  
    173.     }  
    174.     return (T) bean;  
    175. }  

                    doGetBean的大概过程

     

                    1)先试着从单例缓存中获取对象

                    2)从父容器中取定义,有则由父容器创建

                    3)如果是单例,则走单例对象的创建过程:在spring容器中单例对象和非单例对象的创建过程是一样的。都会调用父类AbstractAutowireCapableBeanFactory的createBean()方法。不同的是单例对象之创建一次并且需要缓存起来。DefaultListableBeanFactory的父类DefaultSingletonBeanRegistry提供了对单例对象缓存等支持工作。所以是单例对象的话,会调用DefaultSingletonBeanRegistry的getSingleton()方法,它会间接调用AbstractAutowireCapableBeanFactory的createBean()方法。
                         

                   bean的创建是由AbstractAutowireCapableBeanFactory来定义

     

    [java] view plain copy
     
    1. /** 
    2.  * Central method of this class: creates a bean instance, 
    3.  * populates the bean instance, applies post-processors, etc. 
    4.  * @see #doCreateBean 
    5.  */  
    6. @Override  
    7. protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)  
    8.         throws BeanCreationException   
    9.         {  
    10.   
    11.     if (logger.isDebugEnabled())  
    12.     {  
    13.         logger.debug("Creating instance of bean '" + beanName + "'");  
    14.     }  
    15.     // Make sure bean class is actually resolved at this point.  
    16.     resolveBeanClass(mbd, beanName);  
    17.   
    18.     // Prepare method overrides.  
    19.     try   
    20.     {  
    21.         mbd.prepareMethodOverrides();  
    22.     }  
    23.     catch (BeanDefinitionValidationException ex)   
    24.     {  
    25.         throw new BeanDefinitionStoreException(mbd.getResourceDescription(),  
    26.                 beanName, "Validation of method overrides failed", ex);  
    27.     }  
    28.   
    29.     try   
    30.     {  
    31.         // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.  
    32.         Object bean = resolveBeforeInstantiation(beanName, mbd);  
    33.         if (bean != null)   
    34.         {  
    35.             return bean;  
    36.         }  
    37.     }  
    38.     catch (Throwable ex)   
    39.     {  
    40.         throw new BeanCreationException(mbd.getResourceDescription(), beanName,  
    41.                 "BeanPostProcessor before instantiation of bean failed", ex);  
    42.     }  
    43.   
    44.     Object beanInstance = doCreateBean(beanName, mbd, args);  
    45.     if (logger.isDebugEnabled())   
    46.     {  
    47.         logger.debug("Finished creating instance of bean '" + beanName + "'");  
    48.     }  
    49.     return beanInstance;  
    50. }  

                    createBean会调用doCreateBean方法

     

     

    [java] view plain copy
     
    1. /** 
    2.  * Actually create the specified bean. Pre-creation processing has already happened 
    3.  * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. 
    4.  * <p>Differentiates between default bean instantiation, use of a 
    5.  * factory method, and autowiring a constructor. 
    6.  * @param beanName the name of the bean 
    7.  * @param mbd the merged bean definition for the bean 
    8.  * @param args arguments to use if creating a prototype using explicit arguments to a 
    9.  * static factory method. This parameter must be {@code null} except in this case. 
    10.  * @return a new instance of the bean 
    11.  * @throws BeanCreationException if the bean could not be created 
    12.  * @see #instantiateBean 
    13.  * @see #instantiateUsingFactoryMethod 
    14.  * @see #autowireConstructor 
    15.  */  
    16. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)   
    17. {  
    18.     // Instantiate the bean.  
    19.     BeanWrapper instanceWrapper = null;  
    20.     if (mbd.isSingleton())   
    21.     {  
    22.         instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);  
    23.     }  
    24.     if (instanceWrapper == null)   
    25.     {  
    26.         instanceWrapper = createBeanInstance(beanName, mbd, args);  
    27.     }  
    28.     final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);  
    29.     Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);  
    30.   
    31.     // Allow post-processors to modify the merged bean definition.  
    32.     synchronized (mbd.postProcessingLock)   
    33.     {  
    34.         if (!mbd.postProcessed)   
    35.         {  
    36.             applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);  
    37.             mbd.postProcessed = true;  
    38.         }  
    39.     }  
    40.   
    41.     // Eagerly cache singletons to be able to resolve circular references  
    42.     // even when triggered by lifecycle interfaces like BeanFactoryAware.  
    43.     boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&  
    44.             isSingletonCurrentlyInCreation(beanName));  
    45.     if (earlySingletonExposure)   
    46.     {  
    47.         if (logger.isDebugEnabled())   
    48.         {  
    49.             logger.debug("Eagerly caching bean '" + beanName +  
    50.                     "' to allow for resolving potential circular references");  
    51.         }  
    52.         addSingletonFactory(beanName, new ObjectFactory<Object>() {  
    53.             public Object getObject() throws BeansException   
    54.             {  
    55.                 return getEarlyBeanReference(beanName, mbd, bean);  
    56.             }  
    57.         });  
    58.     }  
    59.   
    60.     // Initialize the bean instance.  
    61.     Object exposedObject = bean;  
    62.     try   
    63.     {  
    64.         populateBean(beanName, mbd, instanceWrapper);  
    65.         if (exposedObject != null)   
    66.         {  
    67.             exposedObject = initializeBean(beanName, exposedObject, mbd);  
    68.         }  
    69.     }  
    70.     catch (Throwable ex)   
    71.     {  
    72.         if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName()))   
    73.         {  
    74.             throw (BeanCreationException) ex;  
    75.         }  
    76.         else   
    77.         {  
    78.             throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);  
    79.         }  
    80.     }  
    81.   
    82.     if (earlySingletonExposure)  
    83.     {  
    84.         Object earlySingletonReference = getSingleton(beanName, false);  
    85.         if (earlySingletonReference != null)   
    86.         {  
    87.             if (exposedObject == bean)   
    88.             {  
    89.                 exposedObject = earlySingletonReference;  
    90.             }  
    91.             else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName))   
    92.             {  
    93.                 String[] dependentBeans = getDependentBeans(beanName);  
    94.                 Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);  
    95.                 for (String dependentBean : dependentBeans)   
    96.                 {  
    97.                     if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean))   
    98.                     {  
    99.                         actualDependentBeans.add(dependentBean);  
    100.                     }  
    101.                 }  
    102.                 if (!actualDependentBeans.isEmpty())   
    103.                 {  
    104.                     throw new BeanCurrentlyInCreationException(beanName,  
    105.                             "Bean with name '" + beanName + "' has been injected into other beans [" +  
    106.                             StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +  
    107.                             "] in its raw version as part of a circular reference, but has eventually been " +  
    108.                             "wrapped. This means that said other beans do not use the final version of the " +  
    109.                             "bean. This is often the result of over-eager type matching - consider using " +  
    110.                             "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");  
    111.                 }  
    112.             }  
    113.         }  
    114.     }  
    115.   
    116.     // Register bean as disposable.  
    117.     try   
    118.     {  
    119.         registerDisposableBeanIfNecessary(beanName, bean, mbd);  
    120.     }  
    121.     catch (BeanDefinitionValidationException ex)   
    122.     {  
    123.         throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);  
    124.     }  
    125.   
    126.     return exposedObject;  
    127. }  

                    doCreateBean流程

     

                    1)会创建一个BeanWrapper对象,用来存放实例化对象

                    2)如果没有指定构造函数,会通过反射拿到一个默认的构造函数

                    3)调用spring的BeanUtils的instantiateClass方法,通过反射创建对象。

                    4)applyMergedBeanDefinitionPostProcessors

                    5)populateBean(),根据注入方式进行注入。根据是否有依赖检查进行依赖检查

                          执行bean注入的时候,会选择注入类型

     

    [java] view plain copy
     
    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. {  
    10.     PropertyValues pvs = mbd.getPropertyValues();  
    11.   
    12.     if (bw == null)   
    13.     {  
    14.         if (!pvs.isEmpty())   
    15.         {  
    16.             throw new BeanCreationException(  
    17.                     mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");  
    18.         }  
    19.         else   
    20.         {  
    21.             // Skip property population phase for null instance.  
    22.             return;  
    23.         }  
    24.     }  
    25.   
    26.     // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the  
    27.     // state of the bean before properties are set. This can be used, for example,  
    28.     // to support styles of field injection.  
    29.     boolean continueWithPropertyPopulation = true;  
    30.   
    31.     if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors())   
    32.     {  
    33.         for (BeanPostProcessor bp : getBeanPostProcessors())   
    34.         {  
    35.             if (bp instanceof InstantiationAwareBeanPostProcessor)   
    36.             {  
    37.                 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  
    38.                 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName))   
    39.                 {  
    40.                     continueWithPropertyPopulation = false;  
    41.                     break;  
    42.                 }  
    43.             }  
    44.         }  
    45.     }  
    46.   
    47.     if (!continueWithPropertyPopulation)   
    48.     {  
    49.         return;  
    50.     }  
    51.   
    52.     if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||  
    53.             mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE)   
    54.     {  
    55.         MutablePropertyValues newPvs = new MutablePropertyValues(pvs);  
    56.   
    57.         // Add property values based on autowire by name if applicable.  
    58.         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) //根据名称注入  
    59.         {  
    60.             autowireByName(beanName, mbd, bw, newPvs);  
    61.         }  
    62.   
    63.         // Add property values based on autowire by type if applicable.  
    64.         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) //根据类型注入  
    65.         {  
    66.             autowireByType(beanName, mbd, bw, newPvs);  
    67.         }  
    68.   
    69.         pvs = newPvs;  
    70.     }  
    71.   
    72.     boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();  
    73.     boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);  
    74.   
    75.     if (hasInstAwareBpps || needsDepCheck)   
    76.     {  
    77.         PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);  
    78.         if (hasInstAwareBpps)   
    79.         {  
    80.             for (BeanPostProcessor bp : getBeanPostProcessors())   
    81.             {  
    82.                 if (bp instanceof InstantiationAwareBeanPostProcessor)   
    83.                 {  
    84.                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  
    85.                     pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);  
    86.                     if (pvs == null)   
    87.                     {  
    88.                         return;  
    89.                     }  
    90.                 }  
    91.             }  
    92.         }  
    93.         if (needsDepCheck)   
    94.         {  
    95.             checkDependencies(beanName, mbd, filteredPds, pvs);  
    96.         }  
    97.     }  
    98.   
    99.     applyPropertyValues(beanName, mbd, bw, pvs);  
    100. }  

                  6)initializeBean(),判断是否实现了BeanNameAware、BeanClassLoaderAware等spring提供的接口,如果实现了,进行默认的注入。同时判断是否实现了InitializingBean接口,如果实现了,调用afterPropertySet方法

     

     

    [java] view plain copy
     
    1. protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {  
    2.     if (System.getSecurityManager() != null) {  
    3.         AccessController.doPrivileged(new PrivilegedAction<Object>() {  
    4.             public Object run() {  
    5.                 invokeAwareMethods(beanName, bean);  
    6.                 return null;  
    7.             }  
    8.         }, getAccessControlContext());  
    9.     }  
    10.     else {  
    11.         invokeAwareMethods(beanName, bean);  
    12.     }  
    13.   
    14.     Object wrappedBean = bean;  
    15.     if (mbd == null || !mbd.isSynthetic()) {  
    16.         wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);  
    17.     }  
    18.   
    19.     try {  
    20.         invokeInitMethods(beanName, wrappedBean, mbd);  
    21.     }  
    22.     catch (Throwable ex) {  
    23.         throw new BeanCreationException(  
    24.                 (mbd != null ? mbd.getResourceDescription() : null),  
    25.                 beanName, "Invocation of init method failed", ex);  
    26.     }  
    27.   
    28.     if (mbd == null || !mbd.isSynthetic()) {  
    29.         wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);  
    30.     }  
    31.     return wrappedBean;  
    32. }  
    33.   
    34. private void invokeAwareMethods(final String beanName, final Object bean) {  
    35.     if (bean instanceof Aware) {  
    36.         if (bean instanceof BeanNameAware) {  
    37.             ((BeanNameAware) bean).setBeanName(beanName);  
    38.         }  
    39.         if (bean instanceof BeanClassLoaderAware) {  
    40.             ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());  
    41.         }  
    42.         if (bean instanceof BeanFactoryAware) {  
    43.             ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);  
    44.         }  
    45.     }  
    46. }  

                    其中invokeInitMethods实现如下:

     

     

    [java] view plain copy
     
    1. protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)  
    2.         throws Throwable {  
    3.   
    4.     boolean isInitializingBean = (bean instanceof InitializingBean);  
    5.     if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {  
    6.         if (logger.isDebugEnabled()) {  
    7.             logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");  
    8.         }  
    9.         if (System.getSecurityManager() != null) {  
    10.             try {  
    11.                 AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {  
    12.                     public Object run() throws Exception {  
    13.                         ((InitializingBean) bean).afterPropertiesSet();  
    14.                         return null;  
    15.                     }  
    16.                 }, getAccessControlContext());  
    17.             }  
    18.             catch (PrivilegedActionException pae) {  
    19.                 throw pae.getException();  
    20.             }  
    21.         }  
    22.         else {  
    23.             ((InitializingBean) bean).afterPropertiesSet();  
    24.         }  
    25.     }  
    26.   
    27.     if (mbd != null) {  
    28.         String initMethodName = mbd.getInitMethodName();  
    29.         if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&  
    30.                 !mbd.isExternallyManagedInitMethod(initMethodName)) {  
    31.             invokeCustomInitMethod(beanName, bean, mbd);  
    32.         }  
    33.     }  

    }  

    Ioc容器初始化过程

     

  • 相关阅读:
    【转】git教程
    Ubuntu下编译运行Kamailio
    windows下编译FreeSwitch
    自己常用的wireshark过滤条件
    CSRF 漏洞原理详解及防御方法
    Sql 注入详解:宽字节注入+二次注入
    Kali下Ettercap 使用教程+DNS欺骗攻击
    Sql注入的分类:数字型+字符型
    Windows Server 2012 R2 配置FTP服务器
    Kali Linux 初始化配置:Apache2 /SSH /FTP
  • 原文地址:https://www.cnblogs.com/doit8791/p/7541376.html
Copyright © 2011-2022 走看看