Spring IOC容器的高级特性

通过之前对spring ioc的剖析,我们了解到:Spring IOC容器对Bean定义资源的定位、读入和解析y以及初始化和依赖注入过程,这些均属于容器的基本功能特性,接下来就容器的一些高级特性我们进行相应的学习。

1. 配置lazy-init属性实现预实例化

我们已经知道IOC容器的初始化过程就是对bean定义资源的定位、载入和注册,此时容器对bean的依赖注入并没有发生,此时:
bean的依赖注入:

  1. 发生时间:在应用程序第一次向容器索取bean时。
  2. 方式:通过getBean方法的调用完成。

但是如果当bean定义资源的<Bean>元素中配置了lazy-init属性后,容器将会在初始化时对所配置的bean进行预实例化,此时:
bean的依赖注入:

  1. 发生时间:容器初始化时已经完成。
  2. 方式:容器初始化。
  3. 当应用程序第一次向容器索取被管理的bean时,直接从容器中获取已经完成依赖注入的bean,提高了应用第一次向容器获取bean的性能。

接下来,通过剖析源码分析其实现过程:
首先从AbstractApplicationContext类的refresh方法开始:

public void refresh() throws BeansException, IllegalStateException {  
       synchronized (this.startupShutdownMonitor) {  
           //调用容器准备刷新的方法
           prepareRefresh();  

           /**调用子类中refreshBeanFactory()方法 
          *启动Bean定义资源文件的过程
          */
           ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  

           //为BeanFactory配置容器特性
           prepareBeanFactory(beanFactory);  
           try {  
               //为容器的子类指定事件处理器  
               postProcessBeanFactory(beanFactory);
  
               //调用所有注册的BeanFactoryPostProcessor的Bean  
               invokeBeanFactoryPostProcessors(beanFactory);  

               /**为BeanFactory注册BeanPost事件处理器.  
               *BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件  
               */
               registerBeanPostProcessors(beanFactory);
  
               //初始化信息源
               initMessageSource();  

               //初始化容器事件传播器.  
               initApplicationEventMulticaster();  

               //调用子类Bean初始化方法  
               onRefresh();  

               //为事件传播器注册事件监听器.  
               registerListeners();  
               //对容器lazy-init属性处理的入口方法
               finishBeanFactoryInitialization(beanFactory);  

              /**初始化容器的生命周期事件处理器
              *并发布容器的生命周期事件  
              */
               finishRefresh();  
           }  
           catch (BeansException ex) {  
               destroyBeans();  
               cancelRefresh(ex);  
               throw ex;  
           }  
       }  
   }

其中:

//对容器lazy-init属性处理的入口方法
finishBeanFactoryInitialization(beanFactory); 

此方法位于类AbstractApplicationContext中,是对配置了预实例化属性的bean进行预初始化过程,源码如下:

   //对配置了lazy-init属性的bean进行预实例化处理  
   protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {  
       if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&  
               beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {  
           beanFactory.setConversionService(  
                   beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));  
       }  
       beanFactory.setTempClassLoader(null);  
       //对容器中所有注册的BeanDefinition缓存,防止在预实例化过程中被修改  
       beanFactory.freezeConfiguration();  
       //对配置了lazy-init属性的单例模式下的bean进行预实例化处理  
       beanFactory.preInstantiateSingletons();  
    }

方法preInstantiateSingletons对配置lazy-init属性单例bean的预实例化:

//对配置lazy-init属性单例bean的预实例化  
public void preInstantiateSingletons() throws BeansException {  
       if (this.logger.isInfoEnabled()) {  
           this.logger.info("Pre-instantiating singletons in " + this);  
       }  
       /**在对配置lazy-init属性单例bean的预实例化过程中,
       *须保证多线程同步,以确保数据的一致性  
       */
       synchronized (this.beanDefinitionMap) {  
           for (String beanName : this.beanDefinitionNames) {  
               //获取指定名称的bean定义  
               RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);  
               /*如果bean不是抽象的,同时是单例模式的bean,
               *并且lazy-init属性配置为false 
               */
               if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {  
                   //如果指定名称的bean是创建容器的bean  
                   if (isFactoryBean(beanName)) {  
                       final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);  
                       //标识是否需要预实例化  
                       boolean isEagerInit;  
                       if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {  
                           isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {  
                               public Boolean run() {  
                                   return ((SmartFactoryBean) factory).isEagerInit();  
                               }  
                           }, getAccessControlContext());  
                       }  
                       else {  
                           isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit();   
                       }  
                       if (isEagerInit) {  
                           getBean(beanName);  
                       }  
                   }  
                   else {  
                       /*如果指定名称的bean不是创建容器的bean  
                       *调用getBean方法,触发容器对bean实例化和依赖注入过程
                       */
                       getBean(beanName);  
                   }  
               }  
           }  
       }  
    }

经过上述分析:
如果设置了lazy-init属性,则容器在完成bean定义的注册之后,会通过getBean方法,触发对指定Bean的初始化和依赖注入过程。
当应用第一次向容器索取所需的bean时,容器不再需要对bean进行初始化和依赖注入,直接从已经完成实例化和依赖注入的bean中取一个线程的bean,提高了第一次获取bean的性能。

2. FactoryBean的实现

FactoryBean:

  1. 概念:工厂bean,本质也是bean。
  2. 作用:产生其他bean实例提供一个工厂方法,该方法用来返回其他bean实例。

源码如下:

//用于产生其他对象  
public interface FactoryBean<T> {  
   //获取容器管理的对象实例  
    T getObject() throws Exception;  
    //获取Bean工厂创建的对象的类型  
    Class<?> getObjectType();  
    /*判断bean工厂创建的对象是否是单态模式,
    *如果是单例模式,则整个容器中只有一个实例对象,  
    *每次请求都返回同一个实例对象
    */
    boolean isSingleton();  
}

类AbstractBeanFactory的doGetBean方法中使用FactoryBean:

  //真正实现向IOC容器获取bean的方法,也是触发依赖注入功能的地方  
   @SuppressWarnings("unchecked")  
   protected <T> T doGetBean(  
           final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)  
           throws BeansException {  
       /**根据指定名称获取被管理bean名称,首先剥离指定名称中对容器的相关依赖  
       *如果指定的是别名,需要将别名转换为规范的bean名称  
       */
       final String beanName = transformedBeanName(name);  
       Object bean;  
       /**先从缓存中取是否已经有被创建过的单例类型的bean,
        *对于单例模式的bean整个IOC容器中只创建一次,不需要重复创建  
        */
       Object sharedInstance = getSingleton(beanName);  
       //IOC容器创建单态模式bean实例对象  
       if (sharedInstance != null && args == null) {  
           if (logger.isDebugEnabled()) {  
               /**如果指定名称的bean在容器中已存在单态模式的bean被创建,
                *直接返回已经创建的bean  
                */
               if (isSingletonCurrentlyInCreation(beanName)) {  
                   logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +  
                           "' that is not fully initialized yet - a consequence of a circular reference");  
               }  
               else {  
                   logger.debug("Returning cached instance of singleton bean '" + beanName + "'");  
               }  
           }  
           //获取给定bean的实例对象
           bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  
       }  
       .........................
   }

方法getObjectForBeanInstance完成FactoryBean的相关处理:

   //获取给定bean的实例对象,主要是完成FactoryBean的相关处理 
   protected Object getObjectForBeanInstance(  
           Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {  
       /**容器得到了bean实例对象,这个实例对象可能是一个普通的bean,也可能是一个工厂bean,  
       *如果是一个工厂bean,则使用它创建一个bean实例对象,  
       *如果调用本身就想获得一个容器的引用,则指定返回这个工厂bean实例对象 
       */  
       if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {  
           throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());  
       }  
       /**如果bean实例不是工厂bean,或者指定名称是容器的解引用,  
       *调用者向获取对容器的引用,则直接返回当前的bean实例  
       */
       if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {  
           return beanInstance;  
       }  
       /**如果处理指定名称不是容器的解引用,或者根据名称获取的bean实例对象是一个工厂Bean  
       *那么使用工厂Bean创建一个bean的实例对象
       */  
       Object object = null;  
       if (mbd == null) {  
           //从Bean工厂缓存中获取给定名称的bean实例对象  
           object = getCachedObjectForFactoryBean(beanName);  
       }  
       /**如果对象为null,
       *让Bean工厂生产给定名称的bean对象实例
       */  
       if (object == null) {  
           FactoryBean factory = (FactoryBean) beanInstance;  
           //如果从Bean工厂生产的bean是单例模式,则进行缓存  
           if (mbd == null && containsBeanDefinition(beanName)) {  
               mbd = getMergedLocalBeanDefinition(beanName);  
           }  
           /**如果从容器得到bean定义信息,并且bean定义信息不是虚构的,
           *则让工厂Bean生产bean实例对象  
           */
           boolean synthetic = (mbd != null && mbd.isSynthetic());  
           //调用方法getObjectFromFactoryBean实现工厂Bean生产bean对象实例的过程  
           object = getObjectFromFactoryBean(factory, beanName, !synthetic);  
       }  
       return object;  
    }

注:
解引用:指所引用对象的本身数据。
类AbstractBeanFactory中方法getObjectFromFactoryBean实现工厂Bean生产bean对象实例的过程:

//Bean工厂生产bean实例对象  
   protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) {  
       //如果工厂Bean是单态模式,并且工厂Bean缓存中存在指定名称的bean实例对象  
       if (factory.isSingleton() && containsSingleton(beanName)) {  
           //须多线程同步,防止数据不一致  
           synchronized (getSingletonMutex()) {  
               //先从工厂Bean缓存中获取指定名称的bean实例对象  
               Object object = this.factoryBeanObjectCache.get(beanName);  
               /**如果工厂Bean缓存中没有指定名称的实例对象,
               *  则生产该实例对象
               */
               if (object == null) {  
                   //调用工厂Bean的getObject方法生产指定bean的实例对象  
                   object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);  
                   //将生产的实例对象添加到工厂Bean缓存中  
                   this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));  
               }  
               return (object != NULL_OBJECT ? object : null);  
           }  
       }  
       //调用工厂Bean的getObject方法生产指定bean的实例对象  
       else {  
           return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);  
       }  
   }  

方法doGetObjectFromFactoryBean调用方法getObject生产指定bean的实例对象:

  //调用工厂Bean的getObject方法生产指定bean的实例对象  
   private Object doGetObjectFromFactoryBean(  
           final FactoryBean factory, final String beanName, final boolean shouldPostProcess)  
           throws BeanCreationException {  
       Object object;  
       try {  
           if (System.getSecurityManager() != null) {  
               AccessControlContext acc = getAccessControlContext();  
               try {  
                   object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {  
                       public Object run() throws Exception {  
                               //BeanFactory接口实现类创建对象 
                               return factory.getObject();  
                           }  
                       }, acc);  
               }  
               catch (PrivilegedActionException pae) {  
                   throw pae.getException();  
               }  
           }  
           else {  
               //调用BeanFactory接口实现类的创建对象方法  
               object = factory.getObject();  
           }  
       }  
       catch (FactoryBeanNotInitializedException ex) {  
           throw new BeanCurrentlyInCreationException(beanName, ex.toString());  
       }  
       catch (Throwable ex) {  
           throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);  
       }  
       //如果创建出来的实例对象为null,或由于单例对象正在创建而返回null  
       if (object == null && isSingletonCurrentlyInCreation(beanName)) {  
           throw new BeanCurrentlyInCreationException(  
                   beanName, "FactoryBean which is currently in creation returned null from getObject");  
       }  
       //为已创建的bean实例对象添加BeanPostProcessor后置处理器  
       if (object != null && shouldPostProcess) {  
           try {  
               object = postProcessObjectFromFactoryBean(object, beanName);  
           }  
           catch (Throwable ex) {  
               throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex);  
           }  
       }  
       return object;  
    }

3. BeanPostProcessor后置处理器的实现

BeanPostProcessor后置处理器

  1. 名称:是一个监听器。
  2. 作用:监听容器触发的Bean声明周期事件。
  3. 影响:后置处理器向容器注册以后,容器中管理的bean就具备了接收IOC容器事件回调的能力。
  4. 使用方式:需要提供一个实现接口BeanPostProcessor的实现类,然后在Bean的配置文件中设置即可。

BeanPostProcessor的源码如下:

   package org.springframework.beans.factory.config;  
   import org.springframework.beans.BeansException;  
   public interface BeanPostProcessor {  
       //为在bean的初始化前提供回调入口  
       Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;  
       //为在bean的初始化之后提供回调入口  
       Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;  
     }

真正实现创建bean对象并进行依赖注入的方法是AbstractAutowireCapableBeanFactory类的doCreateBean方法:

//真正创建bean的方法  
   protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {  
       //创建bean实例对象  
       ……  
       try {  
           //将bean实例对象封装,并且bean定义中配置的属性值赋值给实例对象  
           populateBean(beanName, mbd, instanceWrapper);  
           if (exposedObject != null) {  
               //初始化bean对象  
               exposedObject = initializeBean(beanName, exposedObject, mbd);  
           }  
       }  
       catch (Throwable ex) {  
           if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {  
               throw (BeanCreationException) ex;  
           }  
           else {  
               throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);  
           }  
       }  
       ……  
       //为应用返回所需要的实例对象  
       return exposedObject;  
    }

由上述可知,为bean实例对象添加BeanPostProcessor后置处理器的入口的是initializeBean方法:

   //初始容器创建的bean实例对象,为其添加BeanPostProcessor后置处理器  
   protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {  
       if (System.getSecurityManager() != null) {  
           AccessController.doPrivileged(new PrivilegedAction<Object>() {  
               public Object run() {  
                   invokeAwareMethods(beanName, bean);  
                   return null;  
               }  
           }, getAccessControlContext());  
       }  
       else {  
           //为bean实例对象包装相关属性  
           invokeAwareMethods(beanName, bean);  
       }  
       Object wrappedBean = bean;  
       //回调方法的调用,为Bean实例初始化前做一些处理  
       if (mbd == null || !mbd.isSynthetic()) {  
           wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);  
       }  
       /**调用Bean实例对象初始化的方法,在Spring Bean定义配置,  
       *文件中通过init-method属性指定的
       */  
       try {  
           invokeInitMethods(beanName, wrappedBean, mbd);  
       }  
       catch (Throwable ex) {  
           throw new BeanCreationException(  
                   (mbd != null ? mbd.getResourceDescription() : null),  
                   beanName, "Invocation of init method failed", ex);  
       }  
       /**对BeanPostProcessor后置处理器的postProcessAfterInitialization  
       *回调方法的调用,为Bean实例初始化之后做一些处理  
       */
       if (mbd == null || !mbd.isSynthetic()) {  
           wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);  
       }  
       return wrappedBean;  
   }  

其中,方法applyBeanPostProcessorsBeforeInitialization处理实例对象初始化之前

  //调用BeanPostProcessor后置处理器实例对象初始化之前的处理方法  
   public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)  
           throws BeansException {  
       Object result = existingBean;  
       //遍历容器为所创建的bean添加的所有BeanPostProcessor后置处理器  
       for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {  
           /**调用Bean实例所有的后置处理中的初始化前处理方法,  
           *为Bean实例对象在初始化之前做一些自定义的处理操作  
           */
           result = beanProcessor.postProcessBeforeInitialization(result, beanName);  
           if (result == null) {  
               return result;  
           }  
       }  
       return result;  
   }  

其中,方法applyBeanPostProcessorsAfterInitialization处理实例对象初始化之后

//调用BeanPostProcessor后置处理器实例对象初始化之后的处理方法  
   public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)  
           throws BeansException {  
       Object result = existingBean;  
       //遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器  
       for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {  
           /**调用Bean实例所有的后置处理中的初始化后处理方法,  
           *为Bean实例对象在初始化之后做一些自定义的处理操作 
           */ 
           result = beanProcessor.postProcessAfterInitialization(result, beanName);  
           if (result == null) {  
               return result;  
           }  
       }  
       return result;  
    }

AdvisorAdapterRegistrationManager在Bean对象初始化后注册通知适配器:

//为容器中管理的bean注册面向切面编程的通知适配器  
public class AdvisorAdapterRegistrationManager implements BeanPostProcessor {  
   private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();  
   public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {  
       this.advisorAdapterRegistry = advisorAdapterRegistry;  
   }  
   //BeanPostProcessor在bean对象初始化前的操作  
   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {  
       //直接返回容器创建的Bean对象  
       return bean;  
   }  
   //BeanPostProcessor在bean对象初始化后的操作  
   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  
       if (bean instanceof AdvisorAdapter){  
              /**如果容器创建的bean实例对象是一个切面通知适配器,
              *则向容器的注册
              */
              this.advisorAdapterRegistry.registerAdvisorAdapter((AdvisorAdapter) bean);  
       }  
       return bean;  
   }  
}

未完跟进中......(autowiring实现原理)

4. Spring IOC容器之autowiring实现原理

容器提供两种方式用来管理bean依赖关系:

  1. 显式管理:通过BeanDefinition的属性值和构造方法实现。
  2. autowiring:自动装配功能,不需对bean属性的依赖关系做显式声明,只需配置autowiring属性,容器将通过反射自动查找属性的类型和名称,之后基于属性的类型或名称自动匹配容器中的bean,自动完成依赖注入。

autowiring自动装配特性: 容器对Bean的自动装配发生在容器对Bean依赖注入的过程中。
而容器对bean实例对象的属性注入的处理发生在类AbstractAutoWireCapableBeanFactory中的方法populateBean中:

(1) 属性依赖注入

类AbstractAutoWireCapableBeanFactory的方法populateBean实现bean属性依赖注入的功能:

protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {  
       //获取bean定义的属性值  
       PropertyValues pvs = mbd.getPropertyValues();  
       …
       /**对依赖注入处理,
       *首先处理autowiring自动装配的依赖注入  
       */
       if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||  
               mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
           MutablePropertyValues newPvs = new MutablePropertyValues(pvs);  
           //根据bean名称进行autowiring自动装配处理  
           if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {  
               autowireByName(beanName, mbd, bw, newPvs);  
           }  
           //根据bean类型进行autowiring自动装配处理  
           if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
               autowireByType(beanName, mbd, bw, newPvs);  
           }  
       }  
       //处理非autowiring的属性依赖注入  
        ……  
    }

(2) 根据bean名称或类型进行autowiring自动依赖注入:

根据名称对属性进行自动依赖注入:

   //根据名称对属性进行自动依赖注入  
   protected void autowireByName(  
           String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {  
        //处理 bean对象中非简单属性
       String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);  
       for (String propertyName : propertyNames) {  
           /**如果容器中包含指定名称的bean  
           *调用getBean方法向容器索取指定名称的bean实例,
           *迭代触发对属性的初始化和依赖注入
           */
           if (containsBean(propertyName)) {  
               Object bean = getBean(propertyName);  
               pvs.add(propertyName, bean);  
               //指定名称属性注册依赖bean名称,属性依赖注入  
               registerDependentBean(propertyName, beanName);  
               if (logger.isDebugEnabled()) {  
                   logger.debug("Added autowiring by name from bean name '" + beanName +  
                           "' via property '" + propertyName + "' to bean named '" + propertyName + "'");  
               }  
           }  
           else {  
               if (logger.isTraceEnabled()) {  
                   logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +  
                           "' by name: no matching bean found");  
               }  
           }  
       }  
   }  

根据类型对属性进行自动依赖注入:

 //根据类型对属性进行自动依赖注入  
   protected void autowireByType(  
           String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {  
       //获取用户定义的类型转换器  
       TypeConverter converter = getCustomTypeConverter();  
       if (converter == null) {  
           converter = bw;  
       }  
       //存放解析的要注入的属性  
       Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);  
         //处理bean对象中非简单属性
       String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);  
       for (String propertyName : propertyNames) {  
           try {  
               //获取指定属性名称的属性描述器  
               PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);  
               //不对Object类型的属性进行autowiring自动依赖注入  
               if (!Object.class.equals(pd.getPropertyType())) {  
                   MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);  
                   boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());  
                   //创建一个要被注入的依赖描述  
                   DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);  
                   /**根据容器的bean定义解析依赖关系,
                   *返回所有要被注入的Bean对象  
                   */
                   Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);  
                   if (autowiredArgument != null) {  
                       //为属性赋值所引用的对象  
                       pvs.add(propertyName, autowiredArgument);  
                   }  
                   for (String autowiredBeanName : autowiredBeanNames) {  
                       registerDependentBean(autowiredBeanName, beanName);  
                       if (logger.isDebugEnabled()) {  
                           logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +  
                                   propertyName + "' to bean named '" + autowiredBeanName + "'");  
                       }  
                   }  
                   //释放已自动注入的属性  
                   autowiredBeanNames.clear();  
               }  
           }  
           catch (BeansException ex) {  
               throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);  
           }  
       }  
    }

真正实现属性注入的是类DefaultSingletonBeanRegistry的方法registerDependentBean:

   //为指定的bean注入依赖的bean  
   public void registerDependentBean(String beanName, String dependentBeanName) {  
       //处理bean名称 
       String canonicalName = canonicalName(beanName);  
       /**多线程同步,保证容器内数据的一致性  
       *根据bean名称,  
       *在全部依赖bean名称集合找查找给定名称bean的依赖bean
       */
       synchronized (this.dependentBeanMap) {  
           Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);  
           if (dependentBeans == null) {  
               dependentBeans = new LinkedHashSet<String>(8);  
               this.dependentBeanMap.put(canonicalName, dependentBeans);  
           }  
           //将bean所依赖的bean添加到容器的集合中  
           dependentBeans.add(dependentBeanName);  
       }  
         /**指定名称bean的依赖bean集合找查找给定名称  
         *bean的依赖bean
         */
       synchronized (this.dependenciesForBeanMap) {  
           Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);  
           if (dependenciesForBean == null) {  
               dependenciesForBean = new LinkedHashSet<String>(8);  
               this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);  
           }  
           //将Bean所依赖的Bean添加到容器的集合中  
           dependenciesForBean.add(canonicalName);  
       }  
    }

autowiring的实现过程:

  1. 通过对bean的属性迭代调用getBean方法,完成依赖bean的初始化和依赖注入。
  2. 将依赖bean的属性引用设置到被依赖的bean属性上。
  3. 将依赖bean的名称和被依赖bean的名称存储在容器集合中。

autowiring属性自动依赖注入是一个很方便的特性,可简化开发时的配置,但自动属性依赖注入也有不足。
autowiring属性自动依赖注入的不足:

  1. bean的依赖关系在配置文件中并不具有易读性,不利于维护造成一定困难。
  2. 将依赖注入交给容器自动执行,若配置不当,后果无法评估。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容