spring源码分析IOC和DI

看到一篇好文章http://www.jianshu.com/p/524748c83dde,所以自己也跟着走了一遍。

实例

首先创建一个maven项目,引入spring的几个jar包

引入的jar包

application.xml

HelloWorld


测试类

IOC容器初始化过程

根据上面的例子去理解IoC容器初始化过程:


初始化总过程:

  1. 资源定位(确定工厂创建和bean的配置文件)
  2. 资源装载(在文件系统路径上对IOC配置文件、bean配置进行加载)
  3. 资源解析(解析bean配置,解析xml元素)
  4. 生成bean(根据DOM资源解析成bean)
  5. 在IoC容器中注册(交给IoC容器管理,还有依赖注入的权限)

资源定位

ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");

首先跟进去看看这段代码


继续走

public void refresh() throws BeansException, IllegalStateException {
    Object var1 = this.startupShutdownMonitor;
    synchronized(this.startupShutdownMonitor) {
        //调用容器准备刷新的方法,获取 容器的当时时间,同时给容器设置同步标识  
        this.prepareRefresh();
        //告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从子类的refreshBeanFactory()方法启动  
        //并获取beanFactory
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        //为BeanFactory配置容器特性,例如类加载器、事件处理器等  
        this.prepareBeanFactory(beanFactory);

        try {
            //为容器的某些子类指定特殊的BeanPost事件处理器
            this.postProcessBeanFactory(beanFactory);
            //调用所有注册的BeanFactoryPostProcessor的Bean 
            this.invokeBeanFactoryPostProcessors(beanFactory);
            //为BeanFactory注册BeanPost事件处理器.  
            //BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件
            this.registerBeanPostProcessors(beanFactory);
            //初始化信息源,和国际化相关.  
            this.initMessageSource();
            //初始化容器事件传播器. 
            this.initApplicationEventMulticaster();
            //调用子类的某些特殊Bean初始化方法
            this.onRefresh();
            //为事件传播器注册事件监听器.  
            this.registerListeners();
            //初始化所有剩余的单态Bean.  
            this.finishBeanFactoryInitialization(beanFactory);
            //初始化容器的生命周期事件处理器,并发布容器的生命周期事件 
            this.finishRefresh();
        } catch (BeansException var9) {
            if(this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
            }
            //销毁以创建的单态Bean 
            this.destroyBeans();
            //取消refresh操作,重置容器的同步标识.  
            this.cancelRefresh(var9);
            throw var9;
        } finally {
            this.resetCommonCaches();
        }

    }
}

看 this.obtainFreshBeanFactory();

//关闭前面所有 bean 工厂,为新的上下文环境初始化一个新的 bean 工厂。
//这里需要子类(这里是AbstractRefreshableApplicationContext)来 协助完成资源位置定义 ,bean 载入和向 IOC 容器注册的过程
容器真正调用的是其子类AbstractRefreshableApplicationContext实现的 refreshBeanFactory()方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    this.refreshBeanFactory();//子类实现,调用子类的实现
    ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
    if(this.logger.isDebugEnabled()) {
        this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}

继续看this.refreshBeanFactory();

//交给子类AbstractRefreshableApplicationContext
//在这个方法中,先判断BeanFactory是否存在,如果存在则先销毁beans并关闭beanFactory, 
 //接着创建DefaultListableBeanFactory,并调用loadBeanDefinitions(beanFactory)装载bean
protected final void refreshBeanFactory() throws BeansException {
    if(this.hasBeanFactory()) {
        this.destroyBeans();
        this.closeBeanFactory();
    }

    try {
        //创建IoC容器 
        DefaultListableBeanFactory ex = this.createBeanFactory();
        ex.setSerializationId(this.getId());
        //对IoC容器进行定制化,如设置启动参数,开启注解的自动装配等
        this.customizeBeanFactory(ex);
        //调用载入Bean定义的方法,主要这里使用了一个委派模式,
        //在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器  
        this.loadBeanDefinitions(ex);
        Object var2 = this.beanFactoryMonitor;
        synchronized(this.beanFactoryMonitor) {
            this.beanFactory = ex;
        }
    } catch (IOException var5) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
    }
}

总结:资源定位做的就是:确定工厂位置,执行工厂初始化并刷新,建立好bean资源加载路径。等待bean资源装载。

资源装载

设置工厂配置,刷新容器之后,还要把bean配置给资源加载器。用this.loadBeanDefinitions(beanFactory);去解析。而解析交给子类去实现了。
有下面几种情况



进入AbstractXmlApplicationContext

  protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
   //从beanfactory拿到reader
   // 这里使用XMLBeanDefinitionReader来载入bean定义信息的XML文件
      XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
      //这里配置reader的环境,其中ResourceLoader是我们用来定位bean定义信息资源位置的
      ///因为上下文本身实现了ResourceLoader接口,所以可以直接把上下文作为ResourceLoader传递给XmlBeanDefinitionReader。容器本身也是一个资源加载器        
      beanDefinitionReader.setEnvironment(this.getEnvironment());
      beanDefinitionReader.setResourceLoader(this);
      beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
       //当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制  
      this.initBeanDefinitionReader(beanDefinitionReader);
       //这里转到定义好的XmlBeanDefinitionReader中对载入bean信息进行处理
      this.loadBeanDefinitions(beanDefinitionReader);
  }

AbstractXmlApplicationContext职责为:对applicationContext.xml的解析操作,就是解析工厂的那个xml
AbstractBeanDefinitionReader职责为:从指定的资源加载bean定义,真正实现在其子类,这里是做了些兼容性错误处理。
XmlBeanDefinitionReader是AbstractBeanDefinitionReader的子类,而且是一个真正的实现类 ,是实现BeanDefinitionReader接口的loadBeanDefinitions(Resource var1) 等方法的关键解析类。职责为:读取并真正解析 xml 文件。
AbstractRefreshableApplicationContext中只定义了抽象的loadBeanDefinitions方法,容器真正调用的是其子类AbstractXmlApplicationContext对该方法的实现。(全局搜索SHIFT)
进去this.loadBeanDefinitions(beanDefinitionReader);
由于我们用的是application.xml方式,configResource是null,所以走了getConfigLocation()


走下去进入了AbstractBeanDefinitionReader

public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
    ResourceLoader resourceLoader = this.getResourceLoader();
    if (resourceLoader == null) {//如果没有找到我们需要的ResourceLoader,直接抛出异常
        throw new BeanDefinitionStoreException("Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
    } else {
        int loadCount;
        if (!(resourceLoader instanceof ResourcePatternResolver)) {
            // 这里处理我们在定义位置时使用的各种pattern,需要ResourcePatternResolver来完成
            Resource resource = resourceLoader.getResource(location);
            loadCount = this.loadBeanDefinitions((Resource)resource);
            if (actualResources != null) {
                actualResources.add(resource);
            }

            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
            }

            return loadCount;
        } else {
            try {
                // 这里通过ResourceLoader来完成位置定位
                Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
                // 这里已经把一个位置定义转化为Resource接口,可以供XmlBeanDefinitionReader来使用了
                loadCount = this.loadBeanDefinitions(resources);
                if (actualResources != null) {
                    Resource[] var6 = resources;
                    int var7 = resources.length;

                    for(int var8 = 0; var8 < var7; ++var8) {
                        Resource resource = var6[var8];
                        actualResources.add(resource);
                    }
                }

                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
                }

                return loadCount;
            } catch (IOException var10) {
                throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var10);
            }
        }
    }
}

AbstractBeanDefinitionReader的loadBeanDefinitions方法源码分析可以看出该方法做了以下两件事:
(1)首先,调用资源加载器的获取资源方法resourceLoader.getResource(location),获取到要加载的资源。
(2)其次,真正执行加载功能是其子类XmlBeanDefinitionReader实现的loadBeanDefinitions方法。
此时调用的是DefaultResourceLoader中的getSource()方法定位Resource。
然后我们再仔细看下各个类想拿到资源加载器就是通过getResourceLoader,拿到AbstractBeanDefinitionReader类定义的resourceLoader。这样的话,我们可通过此方式在工程spring下的任何地方拿到资源加载器,“随处加载”了。

  public interface ResourceLoader {
      String CLASSPATH_URL_PREFIX = "classpath:";
      Resource getResource(String var1);
      ClassLoader getClassLoader();
  }

总结:资源加载就是根据之前确定好的bean资源配置路径,拿到资源、拿到加载器,并把bean配置丢进XmlBeanDefinitionReader。等待Bean资源解析。

Bean资源解析

刚刚提到的XmlBeanDefinitionReader就是真正解析xml的类。

    //这里是载入XML形式Bean定义资源文件方法 
    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
       Assert.notNull(encodedResource, "EncodedResource must not be null");
       if(this.logger.isInfoEnabled()) {
           this.logger.info("Loading XML bean definitions from " + encodedResource.getResource());
       }
        //获取当前的线程变量,它是用于保存处理的resource的  
       Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
       if(currentResources == null) {
           currentResources = new HashSet(4);
           this.resourcesCurrentlyBeingLoaded.set(currentResources);//保存当前的resource 
       }
       if(!((Set)currentResources).add(encodedResource)) {
           throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
       } else {
           int var5;
           try {
            //将资源文件转为InputStream的IO流 
               InputStream inputStream = encodedResource.getResource().getInputStream();
   
               try {
                //从InputStream中得到XML的解析源   
                   InputSource inputSource = new InputSource(inputStream);
                   if(encodedResource.getEncoding() != null) {
                       inputSource.setEncoding(encodedResource.getEncoding());
                   }
           //这里是具体的读取过程  
                   var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
               } finally {
               //关闭从Resource中得到的IO流   
                   inputStream.close();
               }
           } catch (IOException var15) {
               throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);
           } finally {
               ((Set)currentResources).remove(encodedResource);
               if(((Set)currentResources).isEmpty()) {
                   this.resourcesCurrentlyBeingLoaded.remove();
               }
   
           }
   
           return var5;
       }
   }
   //从特定XML文件中实际载入Bean定义资源的方法 ,就是转成dom对象后交给这里去进一步处理从而转换出bean
   protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
       try {
       //将XML文件转换为DOM对象,解析过程由documentLoader实现
           Document doc = this.doLoadDocument(inputSource, resource);
            //这里是启动对Bean定义解析的详细过程,该解析过程会用到Spring的Bean配置规则
           return this.registerBeanDefinitions(doc, resource);
       } catch (BeanDefinitionStoreException var4) {
           throw var4;
       }。。。
       }
   }

进入 this.doLoadDocument(inputSource, resource);
走下去有个DocumentLoader接口,进入它的实现类DefaultDocumentLoader

public Document loadDocument(InputSource inputSource, EntityResolver entityResolver, ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
     //创建文件解析器工厂
    DocumentBuilderFactory factory = this.createDocumentBuilderFactory(validationMode, namespaceAware);
    if (logger.isDebugEnabled()) {
        logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");
    }
     //创建文档解析器
    DocumentBuilder builder = this.createDocumentBuilder(factory, entityResolver, errorHandler);
    //解析Spring的Bean定义资源
    return builder.parse(inputSource);
}
//调用了Javaee的JAXP标准,根据定位的Bean定义资源文件,加载读入并转换成为Document对象过程完成
protected DocumentBuilderFactory createDocumentBuilderFactory(int validationMode, boolean namespaceAware) throws ParserConfigurationException {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(namespaceAware);
    if (validationMode != 0) {
        factory.setValidating(true);
        if (validationMode == 3) {
            factory.setNamespaceAware(true);

            try {
                factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
            } catch (IllegalArgumentException var6) {
               。。。
                pcex.initCause(var6);
                throw pcex;
            }
        }
    }

    return factory;
}

总结:Bean资源解析就是,先通过 XML解析器讲Bean定义资源文件转换得到Document对象,但是这堆Document对象没有按照spring的Bean规则的,所以不可直接转换成bean对象。然后完成XML解析变成Document对象后,就调用spring的解析方法按照Spring的Bean规则去对Document进行解析,生成Bean对象。

生成bean

在XmlBeanDefinitionReader中有一个oLoadBeanDefinitions方法里面的
return this.registerBeanDefinitions(doc, resource);进去

  //按照Spring的Bean语义要求 将Bean 定 义  资源解析并转换为容器内部数据结构 
  public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
  //得到BeanDefinitionDocumentReader来对xml格式的BeanDefinition解析  
      BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
      //读取环境的配置设置
      documentReader.setEnvironment(this.getEnvironment());
      //获得容器中注册的Bean数量  
      int countBefore = this.getRegistry().getBeanDefinitionCount();
       //解析过程入口,这里使用了委派模式,BeanDefinitionDocumentReader只是个接口,//具体的解析实现过程有实现类DefaultBeanDefinitionDocumentReader完成 
      documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
      //统计解析的Bean数量
      return this.getRegistry().getBeanDefinitionCount() - countBefore;
  }
  //在此方法真正去转化document对象成为bean
   protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
    return (BeanDefinitionDocumentReader)BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass));
  }

跟着documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
进去是一个BeanDefinitionDocumentReader接口,然后去它的实现类DefaultBeanDefinitionDocumentReader

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    this.readerContext = readerContext;
    this.logger.debug("Loading bean definitions");
    Element root = doc.getDocumentElement();
    this.doRegisterBeanDefinitions(root);
}

在这个类进行详细的document元素解析成我们平常工程用的bean。

在IoC容器中注册

在类DefaultBeanDefinitionDocumentReader生成bean后必然会丢给IoC容器去注册,交给它管理。
根据标签去选择bean元素生成法

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    if (delegate.nodeNameEquals(ele, "import")) {
        this.importBeanDefinitionResource(ele);
    } else if (delegate.nodeNameEquals(ele, "alias")) {
        this.processAliasRegistration(ele);
    //走这里
    } else if (delegate.nodeNameEquals(ele, "bean")) {
        this.processBeanDefinition(ele, delegate);
    } else if (delegate.nodeNameEquals(ele, "beans")) {
        this.doRegisterBeanDefinitions(ele);
    }
}
//进入解析和注册分发啦
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if(bdHolder != null) {
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

        try {
        //注册分发: 继续追踪
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
        } catch (BeanDefinitionStoreException var5) {
            this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
        }

        this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }

}

跟着走进入BeanDefinitionReaderUtils

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
 //得到需要 注册 的 bean名字
    String beanName = definitionHolder.getBeanName();
     //开始注册。锁定registerBeanDefinition方法
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
     // 别名也是可以 通过IOC容器和bean联系起来的进行注册 
    String[] aliases = definitionHolder.getAliases();
    if(aliases != null) {
        String[] var4 = aliases;
        int var5 = aliases.length;

        for(int var6 = 0; var6 < var5; ++var6) {
            String alias = var4[var6];
            registry.registerAlias(beanName, alias);
        }
    }
}

然后根据registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());点进接口BeanDefinitionRegistry。找到BeanDefinitionRegistry的实现类DefaultListableBeanFactory。

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
     //一堆验证beanDefinition的正确性
      。。。
    //先看看在容器里是不是已经有了同名的bean,如果有抛出异常。
    BeanDefinition oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
    if (oldBeanDefinition != null) {
        if (!this.isAllowBeanDefinitionOverriding()) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound.");
        }

        if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
            }
        } else if (!beanDefinition.equals(oldBeanDefinition)) {
            if (this.logger.isInfoEnabled()) {
                this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
            }
        } else if (this.logger.isDebugEnabled()) {
            this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
        }

        this.beanDefinitionMap.put(beanName, beanDefinition);
    } else {
        if (this.hasBeanCreationStarted()) {
            Map var4 = this.beanDefinitionMap;
            synchronized(this.beanDefinitionMap) {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
                updatedDefinitions.addAll(this.beanDefinitionNames);
                updatedDefinitions.add(beanName);
                this.beanDefinitionNames = updatedDefinitions;
                if (this.manualSingletonNames.contains(beanName)) {
                    Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames);
                    updatedSingletons.remove(beanName);
                    this.manualSingletonNames = updatedSingletons;
                }
            }
        } else {
            //这里把bean的名字和Bean定义联系起来放到一个HashMap中去,IOC容器通过这个Map来维护容器里的Bean定义信息。
            this.beanDefinitionMap.put(beanName, beanDefinition);
            //没重复就把bean的名字加到IOC容器中去
            this.beanDefinitionNames.add(beanName);
            this.manualSingletonNames.remove(beanName);
        }

        this.frozenBeanDefinitionNames = null;
    }

    if (oldBeanDefinition != null || this.containsSingleton(beanName)) {
        this.resetBeanDefinition(beanName);
    }

}

总结:在IoC容器中注册就是把beandefinition丢给工厂用hashmap存好

总结IOC容器初始化流程

  1. 通过setConfigLocations载入spring配置文件。
  2. 初始化容器入口通过refresh方法,进入AbstractApplicationContext实现的refresh方法
  3. 然后通过obtainFreshBeanFactory方法进入子类AbstractRefreshableApplicationContext实现的refreshBeanFactory刷新一个容器工厂
  4. 在此创建了DefaultListableBeanFactory类,并调用loadBeanDefinitions(beanFactory)装载bean定义
  5. 接着以AbstractRefreshableApplicationContext为中心回到此类,进入其子类AbstractXmlApplicationContext实现的loadBeanDefinitions方法。对applicationContext.xml的解析操作,就是解析工厂的那个xml
  6. 再接着通过AbstractXmlApplicationContext的loadBeanDefinitions进入到AbstractBeanDefinitionReader类的loadBeanDefinitions。通过获取资源方法resourceLoader.getResource(location),获取到要加载的资源。再真正执行加载功能是其子类XmlBeanDefinitionReader实现的loadBeanDefinitions方法
  7. 接着进入XmlBeanDefinitionReader中的loadBeanDefinitions。(XmlBeanDefinitionReader通过调用其父类中调用的DefaultResourceLoader的getResource方法获取要加载的资源)DocumentLoader将Bean定义资源转换成Document对象
  8. doLoadBeanDefinitions中进入DefaultBeanDefinitionDocumentReader类的registerBeanDefinitions 解析 Document对象
  9. 解析完后,调用DefaultListableBeanFactory类中使用一个HashMap的集合对象存放IoC容器中注册解析的BeanDefinition

IoC容器依赖注入过程

Spring把loadBean和依赖注入分成两个基本的过程,一个是在启动容器的时候完成,建立起一系列 BeanDefinition,这些定义里面同时都包含了对bean依赖关系的描述,不过这里并没有对bean进行实例化,真正实例化的时候是在客户通过容器使用这些bean的时候 - 也就是getbean的时候。这个时候IOC容器根据需要会建立起一系列bean的实例和完成依赖注入。

BeanFactory接口定义了Spring IoC容器的基本功能规范,是Spring IoC容器所应遵守的最底层和最基本的编程规范。BeanFactory接口中定义了几个getBean方法,就是用户向IoC容器索取管理的Bean的方法,


从实例代码的getBean进入,到最后是上图的BeanFactory,然后进入它的实现类AbstractBeanFactory

protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
    //根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖  
    //如果指定的是别名,将别名转换为规范的Bean名称  
    final String beanName = this.transformedBeanName(name);
   //先从缓存中取是否已经有被创建过的单态类型的Bean,对于单态模式的Bean整  
   //个IoC容器中只创建一次,不需要重复创建  
    Object sharedInstance = this.getSingleton(beanName);
    Object bean;
    if (sharedInstance != null && args == null) {
        if (this.logger.isDebugEnabled()) {
           //如果指定名称的Bean在容器中已有单态模式的Bean被创建,直接返回  
           //已经创建的Bean 
            if (this.isSingletonCurrentlyInCreation(beanName)) {
                this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
            } else {
                this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
       //获取给定Bean的实例对象,主要是完成FactoryBean的相关处理  
       //注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是创建创建对象的工厂Bean,两者之间有区别  
        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    } else {
       //缓存没有正在创建的单态模式Bean  
       //缓存中已经有已经创建的原型模式Bean,但是由于循环引用的问题导致实  
       //例化对象失败  
        if (this.isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
       //对IoC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否  
       //能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器  
       //的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找 
        BeanFactory parentBeanFactory = this.getParentBeanFactory();
        //当前容器的父级容器存在,且当前容器中不存在指定名称的Bean 
        if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
            String nameToLookup = this.originalBeanName(name);
            if (args != null) {
                //解析指定Bean名称的原始名称
                return parentBeanFactory.getBean(nameToLookup, args);
            }
            //委派父级容器根据指定名称和类型查找
            return parentBeanFactory.getBean(nameToLookup, requiredType);
        }
        //创建的Bean是否需要进行类型验证,一般不需要
        if (!typeCheckOnly) {
            //向容器标记指定的Bean已经被创建
            this.markBeanAsCreated(beanName);
        }

        try {
            //根据指定Bean名称获取其父级的Bean定义,主要解决Bean继承时子类  
            //合并父类公共属性问题  
            final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
            this.checkMergedBeanDefinition(mbd, beanName, args);
            //获取当前Bean所有依赖Bean的名称 
            String[] dependsOn = mbd.getDependsOn();
            String[] var11;
           //如果当前Bean有依赖Bean 
            if (dependsOn != null) {
                var11 = dependsOn;
                int var12 = dependsOn.length;

                for(int var13 = 0; var13 < var12; ++var13) {
                    String dep = var11[var13];
                    if (this.isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    //把被依赖Bean注册给当前依赖的Bean 
                    this.registerDependentBean(dep, beanName);
                    //递归调用getBean方法,获取当前Bean的依赖Bean 
                    this.getBean(dep);
                }
            }
            //创建单态模式Bean的实例对象
            if (mbd.isSingleton()) {
                //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象  
                sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
                    public Object getObject() throws BeansException {
                        try {
                            //创建一个指定Bean实例对象,如果有父级继承,则合并子//类和父类的定义 
                            return AbstractBeanFactory.this.createBean(beanName, mbd, args);
                        } catch (BeansException var2) {
                            //显式地从容器单态模式Bean缓存中清除实例对象  
                            AbstractBeanFactory.this.destroySingleton(beanName);
                            throw var2;
                        }
                    }
                });
                //获取给定Bean的实例对象  
                bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
           //IoC容器创建原型模式Bean实例对象  
            } else if (mbd.isPrototype()) {
                var11 = null;
               //原型模式(Prototype)是每次都会创建一个新的对象  
                Object prototypeInstance;
                try {
                    //回调beforePrototypeCreation方法,默认的功能是注册当前创//建的原型对象 
                    this.beforePrototypeCreation(beanName);
                    //创建指定Bean对象实例
                    prototypeInstance = this.createBean(beanName, mbd, args);
                } finally {
                   //回调afterPrototypeCreation方法,默认的功能告诉IoC容器指//定Bean的原型对象不再创建了 
                    this.afterPrototypeCreation(beanName);
                }
                //获取给定Bean的实例对象 
                bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            } else {
                //要创建的Bean既不是单态模式,也不是原型模式,则根据Bean定义资源中  
                //配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中  
                //比较常用,如:request、session、application等生命周期  
                String scopeName = mbd.getScope();
                Scope scope = (Scope)this.scopes.get(scopeName);
                //Bean定义资源中没有配置生命周期范围,则Bean定义不合法 
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }

                try {
                    //这里又使用了一个匿名内部类,获取一个指定生命周期范围的实例  
                    Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                        public Object getObject() throws BeansException {
                            AbstractBeanFactory.this.beforePrototypeCreation(beanName);

                            Object var1;
                            try {
                                var1 = AbstractBeanFactory.this.createBean(beanName, mbd, args);
                            } finally {
                                AbstractBeanFactory.this.afterPrototypeCreation(beanName);
                            }

                            return var1;
                        }
                    });
                    //获取给定Bean的实例对象  
                    bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException var21) {
                    throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var21);
                }
            }
        } catch (BeansException var23) {
            this.cleanupAfterBeanCreationFailure(beanName);
            throw var23;
        }
    }
   //对创建的Bean实例对象进行类型检查 
    if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
        try {
            return this.getTypeConverter().convertIfNecessary(bean, requiredType);
        } catch (TypeMismatchException var22) {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var22);
            }

            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    } else {
        return bean;
    }
}

上面,我们可以清楚的看见在创建实例是做了判断

  • 如果Bean定义的单态模式(Singleton),则容器在创建之前先从缓存中查找,以确保整个容器中只存在一个实例对象

  • 如果Bean定义的是原型模式(Prototype),则容器每次都会创建一个新的实例对象。

  • 两者都不是,则根据Bean定义资源中配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中 比较常用,如:request、session、application等生命周期

上面的源码只是定义了根据Bean定义的模式,采取的不同创建Bean实例对象的策略,具体的Bean实例对象的创建过程由实现了ObejctFactory接口的匿名内部类的createBean方法完成,ObejctFactory使用委派模式,具体的Bean实例创建过程交由其实现类AbstractAutowireCapableBeanFactory完成,我们继续分析AbstractAutowireCapableBeanFactory的createBean方法的源码,理解其创建Bean实例的具体实现过程。

//创建Bean实 例对象  
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    if (this.logger.isDebugEnabled()) {
        this.logger.debug("Creating instance of bean '" + beanName + "'");
    }

    RootBeanDefinition mbdToUse = mbd;
    //判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载  
    Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
    //校验和准备Bean中的方法覆盖 
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    try {
        mbdToUse.prepareMethodOverrides();
    } catch (BeanDefinitionValidationException var7) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var7);
    }

    Object beanInstance;
    try {
        //如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象
        beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
        if (beanInstance != null) {
            return beanInstance;
        }
    } catch (Throwable var8) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var8);
    }
    //真正创建Bean的入口  
    beanInstance = this.doCreateBean(beanName, mbdToUse, args);
    if (this.logger.isDebugEnabled()) {
        this.logger.debug("Finished creating instance of bean '" + beanName + "'");
    }

    return beanInstance;
}

进入doCreateBean

  //真正创建bean的方法
  protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) {
    //封装被创建的Bean对象  
    BeanWrapper instanceWrapper = null;
    if(mbd.isSingleton()) {//单态模式的Bean,先从容器中缓存中获取同名Bean
        instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
    }
    //容器没有的话
    if(instanceWrapper == null) {
     //创建实例对象  
        instanceWrapper = this.createBeanInstance(beanName, mbd, args);
    }

    final Object bean = instanceWrapper != null?instanceWrapper.getWrappedInstance():null;
    //获取实例化对象的类型  
    Class<?> beanType = instanceWrapper != null?instanceWrapper.getWrappedClass():null;
    Object var7 = mbd.postProcessingLock;
    //调用PostProcessor后置处理器  
    synchronized(mbd.postProcessingLock) {
        if(!mbd.postProcessed) {
            this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            mbd.postProcessed = true;
        }
    }
    //向容器中缓存单态模式的Bean对象,以防循环引用  
    boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
    if(earlySingletonExposure) {
        if(this.logger.isDebugEnabled()) {
            this.logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
        }
        //这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用  
        this.addSingletonFactory(beanName, new ObjectFactory<Object>() {
            public Object getObject() throws BeansException {
                return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }
     //Bean对象的初始化,依赖注入在此触发  
    //这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean 
    Object exposedObject = bean;
    try {
    //将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
        this.populateBean(beanName, mbd, instanceWrapper);
        if(exposedObject != null) {
        //初始化Bean对象  
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        }
    } catch (Throwable var17) {
      。。。
    }

    if(earlySingletonExposure) {
     //获取指定名称的已注册的单态模式Bean对象  
        Object earlySingletonReference = this.getSingleton(beanName, false);
        if(earlySingletonReference != null) {
         //根据名称获取的以注册的Bean和正在实例化的Bean是同一个  
            if(exposedObject == bean) {
            //当前实例化的Bean初始化完成  
                exposedObject = earlySingletonReference;
            } else if(!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {//当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象 
                String[] dependentBeans = this.getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                String[] var12 = dependentBeans;//用来暂存当前bean
                int var13 = dependentBeans.length;
        //获取当前Bean所依赖的其他Bean 
                for(int var14 = 0; var14 < var13; ++var14) {
                    String dependentBean = var12[var14];
                    //对依赖Bean进行类型检查  
                    if(!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }

                if(!actualDependentBeans.isEmpty()) {
                    。。。
                }
            }
        }
    }
    //注册完成依赖注入的Bean  
    try {
        this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
        return exposedObject;
    } catch (BeanDefinitionValidationException var16) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
    }
  }

除了判断和校验之外,真正实现的是
createBeanInstance:生成Bean所包含的Java对象实例。
populateBean :对Bean属性的依赖注入进行处理。
进入createBeanInstance方法

//创建Bean的实例对象  
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
      //检查确认Bean是可实例化的  
    Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
    //使用工厂方法对Bean进行实例化  
    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    } else if (mbd.getFactoryMethodName() != null) {
        //调用工厂方法实例化  
        return this.instantiateUsingFactoryMethod(beanName, mbd, args);
    } else {//使用容器的自动装配方法进行实例化 
        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            Object var7 = mbd.constructorArgumentLock;
            synchronized(mbd.constructorArgumentLock) {
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    //决定是否使用自动装配的构造器
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
       //autowireConstructor构造器方法配置了自动装配属性,使用容器的自动装配实例化,容器的自动装配是根据参数类型匹配Bean的构造方法
        if (resolved) {
           //根据标记位autowireNecessary而决定采用无参构造器还是自动装配构造器
            return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
        } else {
           //使用Bean的构造方法进行实例化
            Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
           //根据是否有参数还是已经配置了自动装配模式,去选择构造器,无参构造器还是自动装配构造器。
            return ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args) ? this.instantiateBean(beanName, mbd) : this.autowireConstructor(beanName, mbd, ctors, args);
        }
    }
}

进入无参构造器instantiateBean

   //使用默认的无参构造方法实例化Bean对象  
   protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
       try {
           Object beanInstance;
           //获取系统的安全管理接口,JDK标准的安全管理API  
           if(System.getSecurityManager() != null) {
            //这里是一个匿名内置类,根据实例化策略创建实例对象 
               beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                   public Object run() {
                       return AbstractAutowireCapableBeanFactory.this.getInstantiationStrategy().instantiate(mbd, beanName, AbstractAutowireCapableBeanFactory.this);
                   }
               }, this.getAccessControlContext());
           } else {
           //将实例化的对象封装起来
               beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this);
           }
   
           BeanWrapper bw = new BeanWrapperImpl(beanInstance);
           this.initBeanWrapper(bw);
           return bw;
       } catch (Throwable var6) {
           throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6);
       }
   }

我们都看到了,无论什么调用什么构造器,返回的都是统一的BeanWrapper。
BeanWrapper相当于一个代理器,Spring通过BeanWrapper完成Bean属性的填充工作。在Bean实例被InstantiationStrategy创建出来之后,容器主控程序将Bean实例通过BeanWrapper包装起来。

BeanWrapper还有两个顶级类接口,分别是PropertyAccessor和PropertyEditorRegistry。
PropertyAccessor接口定义了各种访问Bean属性的方法,如setPropertyValue(String,Object),setPropertyValues(PropertyValues pvs)等,而PropertyEditorRegistry是属性编辑器的注册表。
所以BeanWrapper实现类BeanWrapperImpl具有了三重身份:

  • 1)Bean包裹器;
  • 2)属性访问器;
  • 3)属性编辑器注册表。

在注入过程中:

createBean开始调用populateBean方法.
首先进行自动装配模式的处理,也就是说对BeanDefiniton中定义自动装配模式的属性进行调整.比如定义了AUTOWIRE_BY_NAME的属性会相应找到匹配该命名的bean.
并且将该被检索到的bean实例值给property,当然这里也肯定通过getBean方法来获取这个需要自动装配的bean实例,并且在BeanWrapper中包装

再看看populateBean:对Bean的属性依赖注入的处理,分为两个部分属性值解析注入

   //将Bean属性设置到生成的实例对象上 
   protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
   //获取容器在解析Bean定义资源时为BeanDefiniton中设置的属性值
       PropertyValues pvs = mbd.getPropertyValues();
       //实例对象为null 
       if(bw == null) {
        //属性值不为空  
           if(!((PropertyValues)pvs).isEmpty()) {
               throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
           }
       } else {
        //在设置属性之前调用Bean的PostProcessor后置处理器  
           boolean continueWithPropertyPopulation = true;
           if(!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
               Iterator var6 = this.getBeanPostProcessors().iterator();
   
               while(var6.hasNext()) {
                   BeanPostProcessor bp = (BeanPostProcessor)var6.next();
                   if(bp instanceof InstantiationAwareBeanPostProcessor) {
                       InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                       if(!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                           continueWithPropertyPopulation = false;
                           break;
                       }
                   }
               }
           }
       //依赖注入开始,首先处理autowire自动装配的注入  
           if(continueWithPropertyPopulation) {
               if(mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
                   MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
                    //对autowire自动装配的处理,根据Bean名称自动装配注入  
                   if(mbd.getResolvedAutowireMode() == 1) {
                       this.autowireByName(beanName, mbd, bw, newPvs);
                   }
                    //根据Bean类型自动装配注入 
                   if(mbd.getResolvedAutowireMode() == 2) {
                       this.autowireByType(beanName, mbd, bw, newPvs);
                   }
   
                   pvs = newPvs;
               }
           //检查容器是否持有用于处理单态模式Bean关闭时的后置处理器 
               boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
             //Bean实例对象没有依赖,即没有继承基类 
               boolean needsDepCheck = mbd.getDependencyCheck() != 0;
               if(hasInstAwareBpps || needsDepCheck) {
               //从实例对象中提取属性描述符  
                   PropertyDescriptor[] filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                   if(hasInstAwareBpps) {
                       Iterator var9 = this.getBeanPostProcessors().iterator();
   
                       while(var9.hasNext()) {
                           BeanPostProcessor bp = (BeanPostProcessor)var9.next();
                           if(bp instanceof InstantiationAwareBeanPostProcessor) {
                               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                               //使用BeanPostProcessor处理器处理属性值  
                               pvs = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                               if(pvs == null) {
                                   return;
                               }
                           }
                       }
                   }
   
                   if(needsDepCheck) {
                   //为要设置的属性进行依赖检查  
                       this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
                   }
               }
             //对属性进行注入  ,解析并注入依赖属性的过程  就在这个方法里面
             /*
             属性转换也有两情况:
             1.属性值类型不需要转换时,不需要解析属性值,直接准备进行依赖注入。
             2.属性值需要进行类型转换时,如对其他对象的引用等,首先需要解析属性值,然后对解析后的属性值进行依赖注入。
             */
               this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
           }
       }
   }

然后进入applyPropertyValues

   //解析并注入依赖属性的过程 
   protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
       if(pvs != null && !pvs.isEmpty()) {
        //封装属性值
           MutablePropertyValues mpvs = null;
           if(System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
            //设置安全上下文,JDK安全机制  
               ((BeanWrapperImpl)bw).setSecurityContext(this.getAccessControlContext());
           }
   
           List original;
           if(pvs instanceof MutablePropertyValues) {           
               mpvs = (MutablePropertyValues)pvs;
                //属性值已经转换  
               if(mpvs.isConverted()) {
                   try {
                    //为实例化对象设置属性值 ,依赖注入真真正正地实现在此!!!!!
                       bw.setPropertyValues(mpvs);
                       return;
                   } catch (BeansException var18) {
                       throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var18);
                   }
               }
            //获取属性值对象的原始类型值  
               original = mpvs.getPropertyValueList();
           } else {
               original = Arrays.asList(pvs.getPropertyValues());
           }
           //获取用户自定义的类型转换  
           TypeConverter converter = this.getCustomTypeConverter();
           if(converter == null) {
               converter = bw;
           }
       //创建一个Bean定义属性值解析器,将Bean定义中的属性值解析为Bean实例对象  
      //的实际值
           BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, (TypeConverter)converter);
            //为属性的解析值创建一个拷贝,将拷贝的数据注入到实例对象中  
           List<PropertyValue> deepCopy = new ArrayList(original.size());
           boolean resolveNecessary = false;
           Iterator var11 = original.iterator();//用迭代器去遍历
   
           while(true) {
               while(var11.hasNext()) {
                   PropertyValue pv = (PropertyValue)var11.next();
                    //属性值不需要转换  
                   if(pv.isConverted()) {
                       deepCopy.add(pv);
                   } else {//属性值需要转换 
                       String propertyName = pv.getName();
                       //原始的属性值,即转换之前的属性值  
                       Object originalValue = pv.getValue();
                         //转换属性值,例如将引用转换为IoC容器中实例化对象引用 !!!!! 对属性值的解析!!
                       Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                       //转换之后的属性值 
                       Object convertedValue = resolvedValue;
                        //属性值是否可以转换  
                       boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                       if(convertible) {
                        //使用用户自定义的类型转换器转换属性值  
                           convertedValue = this.convertForProperty(resolvedValue, propertyName, bw, (TypeConverter)converter);
                       }
               //存储转换后的属性值,避免每次属性注入时的转换工作
                       if(resolvedValue == originalValue) {
                           if(convertible) {
                            //设置属性转换之后的值
                               pv.setConvertedValue(convertedValue);
                           }
   
                           deepCopy.add(pv);
                       } 
                            //属性是可转换的,且属性原始值是字符串类型,且属性的原始类型值不是  
              //动态生成的字符串,且属性的原始值不是集合或者数组类型
                           else if(convertible && originalValue instanceof TypedStringValue && !((TypedStringValue)originalValue).isDynamic() && !(convertedValue instanceof Collection) && !ObjectUtils.isArray(convertedValue)) {
                           pv.setConvertedValue(convertedValue);
                           deepCopy.add(pv);
                       } else {
                           resolveNecessary = true;
                           //重新封装属性的值  
                           deepCopy.add(new PropertyValue(pv, convertedValue));
                       }
                   }
               }
   
               if(mpvs != null && !resolveNecessary) {
                //标记属性值已经转换过  
                   mpvs.setConverted();
               }
               //进行属性依赖注入  ,依赖注入的真真正正实现依赖的注入方法在此!!!
               try {
                   bw.setPropertyValues(new MutablePropertyValues(deepCopy));
                   return;
               } catch (BeansException var19) {
                   throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var19);
               }
           }
       }
   }

总结applyPropertyValues方法(完成属性转换):
属性值类型不需要转换时,不需要解析属性值,直接准备进行依赖注入。
属性值需要进行类型转换时,如对其他对象的引用等,首先需要解析属性值,然后对解析后的属性值进行依赖注入。
当容器在对属性进行依赖注入时,如果发现属性值需要进行类型转换,如属性值是容器中另一个Bean实例对象的引用,则容器首先需要根据属性值解析出所引用的对象,然后才能将该引用对象注入到目标实例对象的属性上去,对属性进行解析的由resolveValueIfNecessary方法实现。可知:创建与注入是个递归的过程
空间限制,都简写了
进入BeanDefinitionValueResolver类的resolveValueIfNecessary方法。
解析引用类型是BeanDefinitionValueResolver类的resolveReference方法
刚刚的AbstractAutowireCapableBeanFactory类中applyPropertyValues方法分发了一个方法实现对属性值的依赖注入setPropertyValues。
找到AbstractPropertyAccessor类中的抽象方法setPropertyValue

很复杂的一个解析方法:将属性的值注入到Bean实例对象中情况如下:

  1. 对于集合类型的属性,将其属性值解析为目标类型的集合后直接赋值给属性
  2. 对于非集合类型的属性,大量使用了JDK的反射和内省机制,通过属性的getter方法(reader method)获取指定属性注入以前的值,同时调用属性的setter方法(writer method)为属性设置注入后的值。

DI总结:

  1. DefaultListableBeanFactory父类AbstractBeanFactory根据Bean的状态定义(单例、存在、原型)进行构造方法分发。分发到AbstractAutowireCapableBeanFactory类的createBean方法
  2. createBean方法负责Bean实例要求状态判断以及再度分发到doCreateBean实现创建实例(再次配置判断)。并在doCreateBean再度分发去createBeanInstance去Bean所包含的Java对象实例以及去populateBean 方法对Bean属性的依赖注入进行处理(以此为责任分发中心)。
  3. 在createBeanInstance方法中真正地根据之前的配置判断设置选择真正合适的构造器(自动装配、无参构造器);
  4. 在populateBean 方法中真正地将Bean属性设置到生成的实例对象上 ,但在过程中注入依赖属性的是在applyPropertyValues方法(完成属性转换),调用BeanDefinitionValueResolver类调用resolveValueIfNecessary方法对属性值的解析,属性的真正注入实现在BeanWrapperImpl类。

这还是站在巨人的肩膀上写的,自己都跟不下去。

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

推荐阅读更多精彩内容