美文网首页
spring源码分析IOC和DI

spring源码分析IOC和DI

作者: lijiaccy | 来源:发表于2017-11-02 14:40 被阅读0次

    看到一篇好文章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类。

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

    相关文章

      网友评论

          本文标题:spring源码分析IOC和DI

          本文链接:https://www.haomeiwen.com/subject/ucvwpxtx.html