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容器初始化过程

 

posted on 2017-09-18 08:36  时间朋友  阅读(375)  评论(0编辑  收藏  举报

导航