Spring源码之IoC

Spring源码之IoC

1. IoC容器:BeanFactory和ApplicationContext

1.1 容器

  • 在IoC的容器设计中,主要有两个容器系列:一个是实现BeanFactory接口的简单容器系列,这系列的容器只实现了容器的基本功能;另一个是ApplicationContext应用上下文,它作为容器的高级形态而存在。
  • 应用上下文在简单容器的基础上,增加了许多面向框架的特性,同时对应用环境做了许多适配。有了这两种基本的同期系列,基本上可以满足用户对IoC容器使用的大部分需求。
  • IoC容器需要为他的具体实现指定基本的功能规范,这个功能规范的设计表现为接口类BeanFactory,它体现了Spring为提供给用户使用的IoC容器所设定的最基本的功能规范。BeanFactory作为一个最基本的接口类出现在Spring的IoC容器体系中
  • 在这些Spring提供的基本IoC容器的接口定义和实现的基础上,Spring通过定义BeanDefinition来管理基于Spring的应用中的各种对象及他们之间的相互依赖关系,BeanDefinition抽象了我们队Bean的定义,是让容器起作用的主要数据类型,IoC容器就是用来管理对象依赖关系的。

1.2 容器设计

接口设计图

  • 接口BeanFactory到HierarchicalBeanFactory,再到ConfigurableBeanFactory,是一条主要的BeanFactory设计规范。BeanFactory接口定义了IoC的基本规范,包含了getBean()这样的IoC容器的基本方法。HierarchicalBeanFactory接口则增加了getParentBeanFactory()接口功能,使得容器具备了双亲IoC容器的管理功能。ConfigurableBeanFactory则定义了对BeanFactory的配置功能,比如通过setParentBeanFactory()设置双亲IoC容器,通过addBeanPostProcessor()配置Bean的后置处理器等
  • 第二条接口设计主线是,以ApplicationContext应用上下文接口为核心的接口设计,BeanFactory到ListableBeanFactory,再到ApplicationContext,再到我们常用的WebApplicationContext或者是ConfigurableApplicationContext接口
  • 这里涉及的都是接口关系,具体的IoC都是在这个接口体系下实现的,比如DefaultListableBeanFactory,这个基本的IoC容器的实现就是实现了ConfigurableBeanFactory,从而成为一个简单IoC容器的实现,像其他容器,比如XmlBeanFactory,都是在DefaultListableBeanFactory的基础上做扩展,ApplicationContext也如此

BeanFactory容器的设计原理

可以看出XmlBeanFactory是中最底层实现的IoC容器,继承了DefaultListableBeanFactory并在此基础上实现了XML读取的功能,DefaultListableBeanFactory作为默认的功能完整的IoC容器,经常被使用。

BeanFactory使用IoC容器的过程

ClassPathResource res = new ClassPathResource("beans.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(res);
  1. 创建IoC配置文件的抽象资源,这个抽象资源包含了BeanDefinition的定义信息
  2. 创建一个BeanFactory,这里使用DefaultListableBeanFactory
  3. 创建一个载入BeanDefinition的读取器,这里使用XmlBeanDefinitionReader来载入XML文件形式的BeanDefinition,通过一个回调配置给BeanFactory
  4. 定义好的资源位置读入配置信息,具体解析过程就交给XmlBeanDefinitionReader来完成

ApplicationContext的设计原理

  • 扩展了MessageSource接口,可支持不同的信息源
  • 对ResourceLoader和Resource的支持,可访问资源,可从不同地方获得Bean定义资源
  • 继承了ApplicationEventPublisher接口,可支持应用事件
  • 以FileSystemXmlApplicationContext实现为例,其基本功能已经在基类AbstractXmlApplicationContext中实现了,子类中的refresh()方法是IoC容器启动时的具体体现。

1.3 BeanFactory和FactoryBean

  • BeanFactory是Factory,也就是对象工厂,Spring的所以Bean都是由BeanFactory来管理的
  • FactoryBean则是一个能产生或者修饰对象生产的工厂Bean
  • 当配置文件中的<bean>的class属性配置的实现类是FactoryBean时,通过getBean()方法返回的不是FactoryBean本身,而是FactoryBean中的getObject()方法所返回的对象,相当于FactoryBean中的getObject()代理了getBean()方法,如果希望获取FactoryBean本身,则需要在getBean(beanName)方法的beanName前显示的加上”&”,例如getBean(“&beanName”)

2. IoC的初始化流程

包含BeanDefinition的Resource定位、载入和注册三个基本过程

通过FileSystemXmlBeanFactory举例说明这个流程

2.1 BeanDefinition的Resource定位

  • Spring通过Resource来定位容器使用的BeanDefinition,这里的Resource并不能由DefaultListableBeanFactory直接使用,要通过BeanDefinitionReader来对这些信息进行处理。
  • DefaultListableBeanFactory只是一个纯粹的IoC容器,需要为它配置特定的读取器才能完成读取Resource的功能。
  • ApplicationContext可直接使用DefaultListableBeanFactory是因为ApplicationContext中已经为我们提供了一系列加载不同Resource的读取器的实现
  • 在ApplicationContext中,可以由FileSystemXmlApplicationContext、ClassPathXmlApplicationContext以及XmlWebApplicationContext等名字可以看到他们提供哪些不用的Resource读入功能

FileSystemXmlApplicationContext继承体系

FileSystemXmlApplicationContext是通过继承AbstractApplicationContext具备了ResourceLoader读入以Resource定义的BeanDefinition的能力,因为AbstractApplicationContext的基类是DefaultResourceLoader

以FileSystemXmlApplicationContext的例子具体看下,读入器的配置是在AbstractRefreshableApplicationContext的refreshBeanFactory方法中进行的

//org.springframework.context.support.FileSystemXmlApplicationContext   
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh,           ApplicationContext parent) throws BeansException {
    super(parent);
    //设置一些配置文件(xml文件等),在父类AbstractRefreshableConfigApplicationContext中实现
    setConfigLocations(configLocations);
    if (refresh) {
      //入口,跳转至AbstractApplicationContext的refresh方法
      refresh();
    }
    //使用了模板模式
    protected Resource getResourceByPath(String path) {
        if (path != null && path.startsWith("/")) {
            path = path.substring(1);
        }
        return new FileSystemResource(path);
    }
}
//org.springframework.context.support.AbstractApplicationContext
public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();
            // 在子类中启动refreshBeanFactory()的地方
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
            try {
                // 设置BeanFactory的后置处理
                postProcessBeanFactory(beanFactory);
                // 调用BeanFactory的后处理器,这些后处理器是在Bean定义中向容器注册的
                invokeBeanFactoryPostProcessors(beanFactory);
                // 注册Bean的后处理器,在Bean的创建过程中调用
                registerBeanPostProcessors(beanFactory);
                // 对上下文的消息源进行初始化
                initMessageSource();
                // 初始化上下文的事件机制
                initApplicationEventMulticaster();
                // 初始化其他特殊的Bean
                onRefresh();
                // 检查监听Bean并且将这些Bean向容器注册
                registerListeners();
                // 实例化所有(non-lazy-init)单例
                finishBeanFactoryInitialization(beanFactory);
                // 发布容器事件,结束Refresh过程
                finishRefresh();
            }
            catch (BeansException ex) {
                logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);
                // 为防止Bean资源占用,在异常处理中,销毁已经在前面过程中生成的单例Bean
                destroyBeans();
                // 重置active状态
                cancelRefresh(ex);
                // Propagate exception to caller.
                throw ex;
            }
        }
    }

//可从obtainFreshBeanFactory()方法中看到refreshBeanFactory()方法的调用
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();//具体实现在AbstractRefreshableApplicationContext类中
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }

可以看见refreshBeanFactory()的具体实现如下

//org.springframework.context.support.AbstractRefreshableApplicationContext
protected final void refreshBeanFactory() throws BeansException {
        //这里判断,如果已经建立了BeanFactory,则销毁并关闭该BeanFactory
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        //这里是创建并设置持有的DefaultListableBeanFactory的地方,同时调用loadBeanDefinition载入         //BeanDefinition信息
        try {
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            customizeBeanFactory(beanFactory);
            //启动对BeanDefinition的载入
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }
//此处为上下文创建DefaultListableBeanFactory的对方,而getInternalParentBeanFactory()的具体实现可以 //参看AbstractApplicationContext的实现,会根据容器已有的双亲IoC容器的信息来生成     //DefaultListableBeanFactory的双亲IoC容器
protected DefaultListableBeanFactory createBeanFactory() {
  return new DefaultListableBeanFactory(getInternalParentBeanFactory());    
}
//子类AbstractXmlApplicationContext中进行实现
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
            throws BeansException, IOException;

在此方法中,通过createBeanFactory()构件了一个IoC容器供ApplicationContext使用,这个容器就是我们之前说的DefaultListableBeanFactory,同时它启动了loadBeanDefinitions(在子类AbstractXmlApplicationContext中实现)来载入BeanDefinition

//org.springframework.context.support.AbstractXmlApplicationContext
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // 创建XmlBeanDefinitionReader,并通过回调设置到BeanFactory中去
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // 设置XmlBeanDefinitionReader,为其配ResourceLoader,因为DefaultResourceLoader是父类,
        // 所以可以直接用this
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        // 启动Bean定义信息载入过程
        initBeanDefinitionReader(beanDefinitionReader);
        loadBeanDefinitions(beanDefinitionReader);
}

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        //以Resource的方式获取配置文件的资源位置
        Resource[] configResources = getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
        //以String的方式获取配置文件的资源位置
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            reader.loadBeanDefinitions(configLocations);
        }
    }
//org.springframework.beans.factory.support.AbstractBeanDefinitionReader
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
        Assert.notNull(locations, "Location array must not be null");
        int counter = 0;
        for (String location : locations) {
            counter += loadBeanDefinitions(location);
        }
        return counter;
}

public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
        return loadBeanDefinitions(location, null);
}

public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
        //这里取得ResourceLoader,使用的是DefaultResourceLoader
        ResourceLoader resourceLoader = getResourceLoader();
        if (resourceLoader == null) {
            throw new BeanDefinitionStoreException(
                    "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
        }
        //对Resource的路径模式进行解析,得到需要的Resource集合,指向我们已经定义好的BeanDefinition信        //可以是多个文件
        if (resourceLoader instanceof ResourcePatternResolver) {
            // Resource pattern matching available.
            try {
                Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
                int loadCount = loadBeanDefinitions(resources);
                if (actualResources != null) {
                    for (Resource resource : resources) {
                        actualResources.add(resource);
                    }
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
                }
                return loadCount;
            }
            catch (IOException ex) {
                throw new BeanDefinitionStoreException(
                        "Could not resolve bean definition resource pattern [" + location + "]", ex);
            }
        }
        else {
            // Can only load single resources by absolute URL.
            Resource resource = resourceLoader.getResource(location);
            int loadCount = loadBeanDefinitions(resource);
            if (actualResources != null) {
                actualResources.add(resource);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
            }
            return loadCount;
        }
}

ResourceLoader的继承图

对于Resource的具体过程,我们可以看看DefaultResourceLoader

//rg.springframework.core.io.DefaultResourceLoader
public Resource getResource(String location) {
        Assert.notNull(location, "Location must not be null");
        if (location.startsWith("/")) {
            return getResourceByPath(location);
        }
        else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
            return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
        }
        else {
            try {
                // Try to parse the location as a URL...
                URL url = new URL(location);
                return new UrlResource(url);
            }
            catch (MalformedURLException ex) {
                // No URL -> resolve as resource path.
                 //这是一个protected方法,默认的实现是的到一个ClassPathContextResource,交给子类实现
                return getResourceByPath(location);
            }
        }
}

上述的getResourceByPath()会被子类FileSystemXmlApplicationContext实现,这个方法返回一个FileSystemResource对象,通过这个对象,Spring就可以进行相关的I/O操作,完成BeanDefinition的定位

2.2 BeanDefinition的载入和解析

  • 载入过程相当于把定义的BeanDefinition在IoC容器中转化成一个Spring内部表示的数据结构的过程
  • IoC容器对Bean的管理和依赖注入功能的实现,是通过对其持有的BeanDefinition进行各种相关操作来完成的
  • 这些BeanDefinition数据在IoC容器中通过一个HashMap来保持和维护

下面将从DefaultListableBeanFactory入手,看IoC容器是如何完成对BeanDefinition载入的,在上面定位的过程中:

//org.springframework.context.support.AbstractXmlApplicationContext
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // 创建XmlBeanDefinitionReader,并通过回调设置到BeanFactory中去
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // 设置XmlBeanDefinitionReader,为其配ResourceLoader,因为DefaultResourceLoader是父类,
        // 所以可以直接用this
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        // 启动Bean定义信息载入过程
        initBeanDefinitionReader(beanDefinitionReader);
        loadBeanDefinitions(beanDefinitionReader);
}

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        //以Resource的方式获取配置文件的资源位置
        Resource[] configResources = getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
        //以String的方式获取配置文件的资源位置
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            reader.loadBeanDefinitions(configLocations);
        }
    }

通过Resource的方式获取配置文件的资源位置原理如下

//org.springframework.beans.factory.support.AbstractBeanDefinitionReader
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
    //如果Resource为空,则停止BeanDefinition的载入
    //然后启动载入BeanDefinition的过程,会遍历整个Resource集合所包含的BeanDefinition信息
    Assert.notNull(resources, "Resource array must not be null");
    int counter = 0;
    for (Resource resource : resources) {   
        counter += loadBeanDefinitions(resource);
    }
    return counter;
}

这里的loadBeanDefinition(Resource res)方法,在此类中没有实现,是一个接口方法,具体的实现在XmlBeanDefinitionReader类中

//org.springframework.beans.factory.xml.XmlBeanDefinitionReader

//调用的入口
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
        return loadBeanDefinitions(new EncodedResource(resource));
}

//载入XML形式的BeanDefinition的地方
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
        Assert.notNull(encodedResource, "EncodedResource must not be null");
        if (logger.isInfoEnabled()) {
            logger.info("Loading XML bean definitions from " + encodedResource.getResource());
        }

        Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
        if (currentResources == null) {
            currentResources = new HashSet<EncodedResource>(4);
            this.resourcesCurrentlyBeingLoaded.set(currentResources);
        }
        if (!currentResources.add(encodedResource)) {
            throw new BeanDefinitionStoreException(
                    "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
        }
        //这里得到XML文件,并得到IO的inputSource准备进行读取
        try {
            InputStream inputStream = encodedResource.getResource().getInputStream();
            try {
                InputSource inputSource = new InputSource(inputStream);
                if (encodedResource.getEncoding() != null) {
                    inputSource.setEncoding(encodedResource.getEncoding());
                }
                 //具体的读取过程
                return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
            }
            finally {
                inputStream.close();
            }
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException(
                    "IOException parsing XML document from " + encodedResource.getResource(), ex);
        }
        finally {
            currentResources.remove(encodedResource);
            if (currentResources.isEmpty()) {
                this.resourcesCurrentlyBeingLoaded.remove();
            }
        }
}

//具体的读取过程,从特定的XML文件中实际载入BeanDefinition的地方
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
            throws BeanDefinitionStoreException {
        try {
            //取得XML文件的Document我对象,这个解析过程是由doLoadDocument完成的,完成这个                   //doLoadDocument是DefaultDocumentLoader,在定义documentLoader的地方创建
            Document doc = doLoadDocument(inputSource, resource);
            //这里启动的时BeanDefinition解析的详细过程,这个解析会使用到Spring的Bean配置规则
            return registerBeanDefinitions(doc, resource);
        }
        catch (BeanDefinitionStoreException ex) {
            throw ex;
        }
        catch (SAXParseException ex) {
            throw new XmlBeanDefinitionStoreException(resource.getDescription(),
                    "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
        }
        catch (SAXException ex) {
            throw new XmlBeanDefinitionStoreException(resource.getDescription(),
                    "XML document from " + resource + " is invalid", ex);
        }
        catch (ParserConfigurationException ex) {
            throw new BeanDefinitionStoreException(resource.getDescription(),
                    "Parser configuration exception parsing XML from " + resource, ex);
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException(resource.getDescription(),
                    "IOException parsing XML document from " + resource, ex);
        }
        catch (Throwable ex) {
            throw new BeanDefinitionStoreException(resource.getDescription(),
                    "Unexpected exception parsing XML document from " + resource, ex);
        }
}

Spring的BeanDefinition按照Bean 语义要求进行解析并转化为容器内部数据结构是在registerBeanDefinitions(doc,resource)中完成的,具体的过程是通过BeanDefinitionDocumentReader来完成的

//org.springframework.beans.factory.xml.XmlBeanDefinitionReader
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        //这里得到BeanDefinitionDocumentReader来对XML的BeanDefinition进行解析
        BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
        documentReader.setEnvironment(getEnvironment());
        int countBefore = getRegistry().getBeanDefinitionCount();
        //具体的解析过程在这个registerBeanDefinitions中完成
        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
        //对载入的Bean的数量进行统计并且返回
        return getRegistry().getBeanDefinitionCount() - countBefore;
}

registerBeanDefinitions在BeanDefinitionDocumentReader的类DefaultBeanDefinitionDocumentReader中实现

//org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        logger.debug("Loading bean definitions");
        Element root = doc.getDocumentElement();
        doRegisterBeanDefinitions(root);
    }

//真正进行载入
protected void doRegisterBeanDefinitions(Element root) {
        //专门处理解析
        BeanDefinitionParserDelegate parent = this.delegate;
        this.delegate = createDelegate(getReaderContext(), root, parent);

        if (this.delegate.isDefaultNamespace(root)) {
          //s首先对profile标签的处理
            String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
            if (StringUtils.hasText(profileSpec)) {
                String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                        profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
                if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                    return;
                }
            }
        }
        //解析前处理,留给子类处理
        preProcessXml(root);
        //进行解析
        parseBeanDefinitions(root, this.delegate);
        //解析后处理,留给子类处理
        postProcessXml(root);

        this.delegate = parent;
}

//进行解析
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        //对默认标签的解析
        if (delegate.isDefaultNamespace(root)) {
            NodeList nl = root.getChildNodes();
            for (int i = 0; i < nl.getLength(); i++) {
                Node node = nl.item(i);
                if (node instanceof Element) {
                    Element ele = (Element) node;
                    if (delegate.isDefaultNamespace(ele)) {
                        parseDefaultElement(ele, delegate);
                    }
                    else {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        //对自定义标签的解析
        else {
            delegate.parseCustomElement(root);
        }
}

//对默认标签的解析
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        //对import标签进行处理
        if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
            importBeanDefinitionResource(ele);
        }
        //对alias标签进行处理
        else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
            processAliasRegistration(ele);
        }
        //对bean标签进行处理
        else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
            processBeanDefinition(ele, delegate);
        }
        //对beans标签进行处理
        else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
            // recurse
            doRegisterBeanDefinitions(ele);
        }
}

//处理普通bean的标签,具体的处理委托刚给BeanDefinitionParserDelegate来完成,ele对应在Spring //BeanDefinition中定义的XML元素
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        /*
        BeanDefinitionHolder是BeanDefinition对象的封装类,封装类BeanDefinition,Bean的名字和别名,        用它来完成向IoC容器注册,得到这个BeanDefinitionHolder就意味着BeanDefinition是通过              BeanDefinitionParserDelegate对XML元素的信息按照Spring的Bean规则进行解析得到的
        */
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                // 这里是向IoC容器注册解析得到BeanDefinition的地方
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to register bean definition with name '" +
                        bdHolder.getBeanName() + "'", ele, ex);
            }
            // 在BeanDefinition向IoC容器注册完以后,发送消息.
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }
}

具体的Spring BeanDefinition的解析是在BeanDefinitionParserDelegate中完成的,这个类里包含了对各种Spring Bean定义规则的处理,例如在XML中定义的一些属性如id,name,aliases等属性元素,将这些元素从XML文件中读取出来后再设置到生成的BeanDefinitionHolder中去

//org.springframework.beans.factory.xml.BeanDefinitionParserDelegate
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
        return parseBeanDefinitionElement(ele, null);
}

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
        //在这里取得<bean>元素中定义的id、name和aliase属性的值
        String id = ele.getAttribute(ID_ATTRIBUTE);
        String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

        List<String> aliases = new ArrayList<String>();
        if (StringUtils.hasLength(nameAttr)) {
            String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
            aliases.addAll(Arrays.asList(nameArr));
        }

        String beanName = id;
        if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
            beanName = aliases.remove(0);
            if (logger.isDebugEnabled()) {
                logger.debug("No XML 'id' specified - using '" + beanName +
                        "' as bean name and " + aliases + " as aliases");
            }
        }

        if (containingBean == null) {
            checkNameUniqueness(beanName, aliases, ele);
        }
        //这个方法会引发对Bean元素的详细解析
        AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
        if (beanDefinition != null) {
            if (!StringUtils.hasText(beanName)) {
                try {
                    if (containingBean != null) {
                        beanName = BeanDefinitionReaderUtils.generateBeanName(
                                beanDefinition, this.readerContext.getRegistry(), true);
                    }
                    else {
                        beanName = this.readerContext.generateBeanName(beanDefinition);
                        // Register an alias for the plain bean class name, if still possible,
                        // if the generator returned the class name plus a suffix.
                        // This is expected for Spring 1.2/2.0 backwards compatibility.
                        String beanClassName = beanDefinition.getBeanClassName();
                        if (beanClassName != null &&
                                beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
                                !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                            aliases.add(beanClassName);
                        }
                    }
                    if (logger.isDebugEnabled()) {
                        logger.debug("Neither XML 'id' nor 'name' specified - " +
                                "using generated bean name [" + beanName + "]");
                    }
                }
                catch (Exception ex) {
                    error(ex.getMessage(), ele);
                    return null;
                }
            }
            String[] aliasesArray = StringUtils.toStringArray(aliases);
            return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
        }

        return null;
}

//bean元素的详细解析
public AbstractBeanDefinition parseBeanDefinitionElement(
            Element ele, String beanName, BeanDefinition containingBean) {
        //这里只读取<bean>中设置的class名字,然后载入到BeanDefinition中去,只是做个记录,并不会实例化
        //实例化是在依赖注入中完成的
        this.parseState.push(new BeanEntry(beanName));

        String className = null;
        if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
            className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
        }

        try {
            String parent = null;
            if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
                parent = ele.getAttribute(PARENT_ATTRIBUTE);
            }
            //这里生成需要的BeanDefinition对象, 为Bean定义信息的载入做准备
            AbstractBeanDefinition bd = createBeanDefinition(className, parent);
            //这里对当前的Bean元素进行属性解析,并设置description的信息
            parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
            //对<bean>元素的信息(子元素)进行解析的地方
            parseMetaElements(ele, bd);
            parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
            parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
            //解析<bean>的构造函数设置
            parseConstructorArgElements(ele, bd);
             //解析<bean>的property设置
            parsePropertyElements(ele, bd);
            parseQualifierElements(ele, bd);

            bd.setResource(this.readerContext.getResource());
            bd.setSource(extractSource(ele));

            return bd;
        }
        catch (ClassNotFoundException ex) {
            error("Bean class [" + className + "] not found", ele, ex);
        }
        catch (NoClassDefFoundError err) {
            error("Class that bean class [" + className + "] depends on not found", ele, err);
        }
        catch (Throwable ex) {
            error("Unexpected failure during bean definition parsing", ele, ex);
        }
        finally {
            this.parseState.pop();
        }

        return null;
}

经过这样逐层的解析,我们在XML文件中定义的BeanDefinition就被整个载入到了IoC容器中,并在容器中建立了数据映射。这些数据结构可以以AbstractBeanDefinition为入口,让IoC容器执行索引、查询和操作。但是目前重要的依赖注入实际上还没发生,只是存在一些静态的配置信息,此时容器还没完全起作用,要完全发挥容器的作用,还需要完成数据项容器的注册

2.3 BeanDefinition在IoC容器中的注册

上述的载入和解析过程,用户定义的BeanDefinition信息已经在IoC容器内建立了自己的数据结构以及相应的数据表示,但是还不能直接供IoC容器使用,需要在IoC容器中对这些BeanDefinition进行注册。

注册是通过DefaultListableBeanFactory中的HashMap来持有载入的BeanDefinition的,这个HashMap的定义如下:

    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);

将解析得到的BeanDefinition向IoC容器中的beanDefinitionMap注册的过程是在载入BeanDefinition完成后进行的。DefaultListableBeanFactory中实现了BeanDefinitionRegistry的接口,这个就看就是完成BeanDefinition向容器的注册。如果遇到同名的BeanDefinition,进行处理的时候需要依据allowBeanDefinitionOverriding的配置来完成

//org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                //这里进行注册
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to register bean definition with name '" +
                        bdHolder.getBeanName() + "'", ele, ex);
            }
            // Send registration event.
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }
    }
//org.springframework.beans.factory.support.BeanDefinitionReaderUtils
public static void registerBeanDefinition(
            BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
            throws BeanDefinitionStoreException {

        // Register bean definition under primary name.
        String beanName = definitionHolder.getBeanName();
        //其实是调用DefaultListableBeanFactory实现类进行完成注册
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

        // Register aliases for bean name, if any.
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            for (String alias : aliases) {
                registry.registerAlias(beanName, alias);
            }
        }
    }
//org.springframework.beans.factory.support.DefaultListableBeanFactory
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {

        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");

        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition) beanDefinition).validate();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Validation of bean definition failed", ex);
            }
        }

        BeanDefinition oldBeanDefinition;

        oldBeanDefinition = this.beanDefinitionMap.get(beanName);
        if (oldBeanDefinition != null) {
            if (!isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
                        "': There is already [" + oldBeanDefinition + "] bound.");
            }
            else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
                // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
                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 (this.logger.isInfoEnabled()) {
                    this.logger.info("Overriding bean definition for bean '" + beanName +
                            "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                }
            }
        }
        //这是正常的BeanDefinition注册过程,
        else {
            this.beanDefinitionNames.add(beanName);
            this.manualSingletonNames.remove(beanName);
            this.frozenBeanDefinitionNames = null;
        }
        this.beanDefinitionMap.put(beanName, beanDefinition);

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

完成了BeanDefinition的注册,IoC容器DefaultListableBeanFactory中已经建立了整个Bean的配置信息,而且这些BeanDefinition都可以被容器使用了,他们都在beanDefinitionMap中被检索和使用,容器的作用就是对这些信息进行处理和维护。这些信息是容器建立依赖反转的基础。

3. IoC的依赖注入

依赖注入的过程是用户第一次向IoC容器索要Bean时触发的,也可通过在配置文件中控制lazy-init属性来让容器完成Bean的预实例化。在IoC容器接口BeanFactory中,有一个getBean的接口定义,这个接口的实现就是触发依赖注入的地方。

下面从DefaultListableBeanFactory的基类AbstractBeanFactory查看getBean的实现

//org.springframework.beans.factory.support.AbstractBeanFactory
    @Override
    public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }

    @Override
    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        return doGetBean(name, requiredType, null, false);
    }

    @Override
    public Object getBean(String name, Object... args) throws BeansException {
        return doGetBean(name, null, args, false);
    }

    public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
        return doGetBean(name, requiredType, args, false);
    }

    //实际取得Bean的地方,也是触发依赖注入发生的地方
    protected <T> T doGetBean(
            final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
            throws BeansException {

        final String beanName = transformedBeanName(name);
        Object bean;

        // 先从缓存中取得Bean,处理那些已经被创建过的单例模式的Bean,对这种Bean的请求不需要重复创建.
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            //这里完成的是FactoryBean的相关处理,以取得FactoryBean的生产结果
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {
            // 只有单例情况下才回尝试解决循环依赖,Prototype模式下如果存在循环依赖则抛出异常
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // 这里对IoC容器中的BeanDefinition是否存在进行检查,检查是否能在当前的BeanFactory中取得             //需要的Bean,如果在当前工厂中取不到,则到双亲BeanFactory中去取,一直向上查找
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);
                if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                //根据Bean的名字获取BeanDefinition
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

    // 获取当前Bean的所以依赖Bean,这样会触发getBean的递归调用,直到取到一个没有任何依赖的Bean为止
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dependsOnBean : dependsOn) {
                        if (isDependent(beanName, dependsOnBean)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
                        }
                        registerDependentBean(dependsOnBean, beanName);
                        getBean(dependsOnBean);
                    }
                }
                /*
                这里通过调用createBean方法创建Singleton bean的实例,这里有一个回调函数getObject
                会在getSingleton中调用ObjectFactory的createBean
                */
                // 创建单例bean.
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            catch (BeansException ex) {
                                // Explicitly remove instance from singleton cache: It might have been put there
                                // eagerly by the creation process, to allow for circular reference resolution.
                                // Also remove any beans that received a temporary reference to the bean.
                                destroySingleton(beanName);
                                throw ex;
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                //创建prototype bean
                else if (mbd.isPrototype()) {
                    // It's a prototype -> create a new instance.
                    Object prototypeInstance = null;
                    try {
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }

                else {
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
                    }
                    try {
                        Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                            @Override
                            public Object getObject() throws BeansException {
                                beforePrototypeCreation(beanName);
                                try {
                                    return createBean(beanName, mbd, args);
                                }
                                finally {
                                    afterPrototypeCreation(beanName);
                                }
                            }
                        });
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {
                        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",
                                ex);
                    }
                }
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }

        // 这里对创建的Bean进行类型检查,如果没有问题,就返回这个新创建的Bean,这个Bean已经是包含了依         //赖关系的Bean
        if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
            try {
                return getTypeConverter().convertIfNecessary(bean, requiredType);
            }
            catch (TypeMismatchException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type [" +
                            ClassUtils.getQualifiedName(requiredType) + "]", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

getBean是依赖注入的起点,之后会调用createBean,在createBean的实现过程中,Bean对象会依据BeanDefinition定义要求生产,在AbstractAutowireCapableBeanFactory实现了这个createBean,createBean不但生成了需要的Bean,还对Bean初始化进行了处理,比如实现了在BeanDefinition中的init-method属性定义,Bean后置处理器等

//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
    protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
            throws BeanCreationException {

        if (logger.isDebugEnabled()) {
            logger.debug("Creating instance of bean '" + beanName + "'");
        }
        // 判断需要创建的Bean是否可以实例化,这个类是否可以通过类装载器来载入
        resolveBeanClass(mbd, beanName);

        // 验证及准备覆盖的方法.
        try {
            mbd.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // 如果Bean配置了PostProcessor,那么这里返回的是一个Proxy,Aop功能就是这里判断的
            Object bean = resolveBeforeInstantiation(beanName, mbd);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }
        //这里是创建Bean的调用
        Object beanInstance = doCreateBean(beanName, mbd, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }

    //接着到doCreateBean中去看看Bean是如何产生的
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
        // 这个BeanWrapper是用来持有创建出来的Bean对象的.
        BeanWrapper instanceWrapper = null;
        //如果是单例,则先把缓存中的同名Bean清除
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        //创建Bean,由createBeanInstance来完成
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

        // Allow post-processors to modify the merged bean definition.
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                mbd.postProcessed = true;
            }
        }

        // 是否需要提前曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            //为避免后期循环依赖,可以再bean初始化完成前将创建实例的ObjectFactory攻击如工厂
            addSingletonFactory(beanName, new ObjectFactory<Object>() {
                @Override
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

        // 这里是对Bean的初始化,依赖注入往往在这里发生,这个exposedObject在初始化处理完以后会返回作为
        //依赖注入完成后的Bean
        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
            }
        }

        if (earlySingletonExposure) {
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName,
                                "Bean with name '" + beanName + "' has been injected into other beans [" +
                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                "] in its raw version as part of a circular reference, but has eventually been " +
                                "wrapped. This means that said other beans do not use the final version of the " +
                                "bean. This is often the result of over-eager type matching - consider using " +
                                "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        // Register bean as disposable.
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }

这里可以看出与依赖注入关系特别密切的方法由createBeanInstance和populateBean,createBeanInstance中生成了Bean所包含的Java对象,这个对象的生成有很多种不同的方式,可以通过工厂方法生成,也可以通过容器的autowire特性生成,这些生成的方式都是由相关BeanDefinition来指定的

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
        // 确认需要创建的Bean实例的类可以实例化
        Class<?> beanClass = resolveBeanClass(mbd, beanName);
        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());
        }
        //这里使用工厂方法对Bean进行实例化
        if (mbd.getFactoryMethodName() != null)  {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // Shortcut when re-creating the same bean...
        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        if (resolved) {
            if (autowireNecessary) {
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                return instantiateBean(beanName, mbd);
            }
        }

        // 使用构造函数进行实例化.
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        // 使用默认的构造函数进行实例化
        return instantiateBean(beanName, mbd);
    }

//最常见的实例化过程instantiateBean
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
        //使用默认的实例化策略对Bean进行实例化,默认的实例化策略就是                                    //CglibSubclassingInstantiationStrategy,也就是使用CGLIB进行实例化
        try {
            Object beanInstance;
            final BeanFactory parent = this;
            if (System.getSecurityManager() != null) {
                beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        return getInstantiationStrategy().instantiate(mbd, beanName, parent);
                    }
                }, getAccessControlContext());
            }
            else {
                beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
            }
            BeanWrapper bw = new BeanWrapperImpl(beanInstance);
            initBeanWrapper(bw);
            return bw;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
        }
    }

这里用CGLIB对Bean进行实例化,CGLIB是一个常用的字节码生成器的类库。SimpleInstantiationStrategy是Spring 用来生成Bean对象的莫人类,它提供了两种实例化Java对象的方法,一种是通过BeanUtils,它使用了JVM的反射功能,一种是前面提到的CGLIB来生成

//org.springframework.beans.factory.support.SimpleInstantiationStrategy 
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
        // Don't override the class with CGLIB if no overrides.
        if (bd.getMethodOverrides().isEmpty()) {
            Constructor<?> constructorToUse;
            synchronized (bd.constructorArgumentLock) {
                //这里取得指定的构造器或者生成对象的工厂方法来对Bean进行实例化
                constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
                if (constructorToUse == null) {
                    final Class<?> clazz = bd.getBeanClass();
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }
                    try {
                        if (System.getSecurityManager() != null) {
                            constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
                                @Override
                                public Constructor<?> run() throws Exception {
                                    return clazz.getDeclaredConstructor((Class[]) null);
                                }
                            });
                        }
                        else {
                            constructorToUse =  clazz.getDeclaredConstructor((Class[]) null);
                        }
                        bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                    }
                    catch (Exception ex) {
                        throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                    }
                }
            }
            //通过BeanUtils进行实例化,这个BeanUtils的实例化通过Constructor来实例化Bean
            return BeanUtils.instantiateClass(constructorToUse);
        }
        else {
            // 通过CGLIB来实例化对象
            return instantiateWithMethodInjection(bd, beanName, owner);
        }
    }

此时已经分析了实例化Bean 对象的整个过程了,在这个基础上要了解Spring是怎样对这些对象进行处理的,也就是Bean对象生成以后怎样把这些Bean对象的依赖关系设置好,完成整个依赖注入过程。这个过程设计对各种Bean对象的属性的处理过程,处理这些依赖关系的依据就是BeanDefinition,具体可在populateBean方法中查看

//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        //这里取得在BeanDefinition中设置的Property值,这些property来自对BeanDefinition的解析
        PropertyValues pvs = mbd.getPropertyValues();

        if (bw == null) {
            if (!pvs.isEmpty()) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
            else {
                // Skip property population phase for null instance.
                return;
            }
        }

        boolean continueWithPropertyPopulation = true;

        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }

        if (!continueWithPropertyPopulation) {
            return;
        }
        //开始进行依赖注入,先处理autowire的注入
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

            // 这里是对autowire注入的处理,可以根据Bean的名字或者类型来完成Bean的autowire
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }

            // Add property values based on autowire by type if applicable.
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }

            pvs = newPvs;
        }

        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

        if (hasInstAwareBpps || needsDepCheck) {
            PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            if (hasInstAwareBpps) {
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvs == null) {
                            return;
                        }
                    }
                }
            }
            if (needsDepCheck) {
                checkDependencies(beanName, mbd, filteredPds, pvs);
            }
        }
        //对属性进行注入
        applyPropertyValues(beanName, mbd, bw, pvs);
    }

//通过该方法进行对属性解析然后注入  
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        if (pvs == null || pvs.isEmpty()) {
            return;
        }

        MutablePropertyValues mpvs = null;
        List<PropertyValue> original;

        if (System.getSecurityManager() != null) {
            if (bw instanceof BeanWrapperImpl) {
                ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
            }
        }

        if (pvs instanceof MutablePropertyValues) {
            mpvs = (MutablePropertyValues) pvs;
            if (mpvs.isConverted()) {
                // Shortcut: use the pre-converted values as-is.
                try {
                    bw.setPropertyValues(mpvs);
                    return;
                }
                catch (BeansException ex) {
                    throw new BeanCreationException(
                            mbd.getResourceDescription(), beanName, "Error setting property values", ex);
                }
            }
            original = mpvs.getPropertyValueList();
        }
        else {
            original = Arrays.asList(pvs.getPropertyValues());
        }

        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {
            converter = bw;
        }
        //注意这个BeanDefinitionValueResolver对BeanDefinition的解析是在这个valueResolver中完成
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

        // 为解析值创建一个副本,副本的数据将会被注入到Bean中
        List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
        boolean resolveNecessary = false;
        for (PropertyValue pv : original) {
            if (pv.isConverted()) {
                deepCopy.add(pv);
            }
            else {
                String propertyName = pv.getName();
                Object originalValue = pv.getValue();
                Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                Object convertedValue = resolvedValue;
                boolean convertible = bw.isWritableProperty(propertyName) &&
                        !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                if (convertible) {
                    convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
                }
                // Possibly store converted value in merged bean definition,
                // in order to avoid re-conversion for every created bean instance.
                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();
        }

        // 这里是依赖注入发生的地方,会在BeanWarpperImpl中完成
        try {
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
        catch (BeansException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
        }
    }

这里通过使用BeanDefinitionValueResolver来对BeanDefinition进行解析,然后注入到property中

//org.springframework.beans.factory.support.BeanDefinitionValueResolver
    public Object resolveValueIfNecessary(Object argName, Object value) {
        // 这里对runtimeBeanReference进行解析,RuntimeBeanReference是在对BeanDefinition
        // 进行解析的时候生成的数据对象
        if (value instanceof RuntimeBeanReference) {
            RuntimeBeanReference ref = (RuntimeBeanReference) value;
            return resolveReference(argName, ref);
        }
        else if (value instanceof RuntimeBeanNameReference) {
            String refName = ((RuntimeBeanNameReference) value).getBeanName();
            refName = String.valueOf(doEvaluate(refName));
            if (!this.beanFactory.containsBean(refName)) {
                throw new BeanDefinitionStoreException(
                        "Invalid bean name '" + refName + "' in bean reference for " + argName);
            }
            return refName;
        }
        else if (value instanceof BeanDefinitionHolder) {
            // Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
            BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
            return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
        }
        else if (value instanceof BeanDefinition) {
            // Resolve plain BeanDefinition, without contained name: use dummy name.
            BeanDefinition bd = (BeanDefinition) value;
            String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
                    ObjectUtils.getIdentityHexString(bd);
            return resolveInnerBean(argName, innerBeanName, bd);
        }
        //这里对ManageArray进行解析
        else if (value instanceof ManagedArray) {
            // May need to resolve contained runtime references.
            ManagedArray array = (ManagedArray) value;
            Class<?> elementType = array.resolvedElementType;
            if (elementType == null) {
                String elementTypeName = array.getElementTypeName();
                if (StringUtils.hasText(elementTypeName)) {
                    try {
                        elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
                        array.resolvedElementType = elementType;
                    }
                    catch (Throwable ex) {
                        // Improve the message by showing the context.
                        throw new BeanCreationException(
                                this.beanDefinition.getResourceDescription(), this.beanName,
                                "Error resolving array type for " + argName, ex);
                    }
                }
                else {
                    elementType = Object.class;
                }
            }
            return resolveManagedArray(argName, (List<?>) value, elementType);
        }
        //这里对ManagedList进行解析
        else if (value instanceof ManagedList) {
            // May need to resolve contained runtime references.
            return resolveManagedList(argName, (List<?>) value);
        }
         //这里对ManagedSet进行解析
        else if (value instanceof ManagedSet) {
            // May need to resolve contained runtime references.
            return resolveManagedSet(argName, (Set<?>) value);
        }
        //这里对ManagedMap进行解析
        else if (value instanceof ManagedMap) {
            // May need to resolve contained runtime references.
            return resolveManagedMap(argName, (Map<?, ?>) value);
        }
        //这里对ManagedProperties进行解析
        else if (value instanceof ManagedProperties) {
            Properties original = (Properties) value;
            Properties copy = new Properties();
            for (Map.Entry<Object, Object> propEntry : original.entrySet()) {
                Object propKey = propEntry.getKey();
                Object propValue = propEntry.getValue();
                if (propKey instanceof TypedStringValue) {
                    propKey = evaluate((TypedStringValue) propKey);
                }
                if (propValue instanceof TypedStringValue) {
                    propValue = evaluate((TypedStringValue) propValue);
                }
                copy.put(propKey, propValue);
            }
            return copy;
        }
      //这里对TypedStringValue进行解析
        else if (value instanceof TypedStringValue) {
            // Convert value to target type here.
            TypedStringValue typedStringValue = (TypedStringValue) value;
            Object valueObject = evaluate(typedStringValue);
            try {
                Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
                if (resolvedTargetType != null) {
                    return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
                }
                else {
                    return valueObject;
                }
            }
            catch (Throwable ex) {
                // Improve the message by showing the context.
                throw new BeanCreationException(
                        this.beanDefinition.getResourceDescription(), this.beanName,
                        "Error converting typed String value for " + argName, ex);
            }
        }
        else {
            return evaluate(value);
        }
    }

/**
    以对RuntimeBeanReference类型的注入为例
**/
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
        try {
          //从RuntimeBeanReference取得reference的名字,这个RuntimeBeanReference是在载入                     //BeanDefinition的时候配置生成的 
            String refName = ref.getBeanName();
            refName = String.valueOf(doEvaluate(refName));
          //如果ref是在双亲IoC容器中则到双亲IoC中获取
            if (ref.isToParent()) {
                if (this.beanFactory.getParentBeanFactory() == null) {
                    throw new BeanCreationException(
                            this.beanDefinition.getResourceDescription(), this.beanName,
                            "Can't resolve reference to bean '" + refName +
                            "' in parent factory: no parent factory available");
                }
                return this.beanFactory.getParentBeanFactory().getBean(refName);
            }
          //在当前IoC容器中获取,会触发getBean过程,如果依赖注入没法说,会触发相应的依赖注入
            else {
                Object bean = this.beanFactory.getBean(refName);
                this.beanFactory.registerDependentBean(refName, this.beanName);
                return bean;
            }
        }
        catch (BeansException ex) {
            throw new BeanCreationException(
                    this.beanDefinition.getResourceDescription(), this.beanName,
                    "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
        }
    }

在完成这个解析过程后,已经为依赖注入准备好了条件,这是真正把Bean对象设置到他所在的另一个Bean的属性中去的地方,其中的属性是各种各样的,依赖注入的发生是在BeanWrapper的setPropertyValues中实现,具体的完成确实在BeanWrapper子类BeanWrapperImpl实现的

    private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
        String propertyName = tokens.canonicalName;
        String actualName = tokens.actualName;

        if (tokens.keys != null) {
            // Apply indexes and map keys: fetch value for all keys but the last one.
            PropertyTokenHolder getterTokens = new PropertyTokenHolder();
            getterTokens.canonicalName = tokens.canonicalName;
            getterTokens.actualName = tokens.actualName;
            getterTokens.keys = new String[tokens.keys.length - 1];
            System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
            Object propValue;
            try {
                propValue = getPropertyValue(getterTokens);
            }
            catch (NotReadablePropertyException ex) {
                throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
                        "Cannot access indexed value in property referenced " +
                        "in indexed property path '" + propertyName + "'", ex);
            }
            // Set value for last key.
            String key = tokens.keys[tokens.keys.length - 1];
            if (propValue == null) {
              ……
            }
              ……    ……

 }

至此完成了Spring 的依赖注入

4. 循环依赖

循环依赖就是循环引用,就是两个或多个bean相互之间的持有对方,循环调用时无法解决的,除非有终结条件,否则就是死循环,最终导致内存溢出错误

Spring中将循环依赖的处理分成了三种情况

  1. 构造器循环依赖:表示通过构造器注入构成的循环依赖,此依赖是无法解决的,只能抛出BeanCurrentlyInCreationException异常表示循环依赖。Spring容器将每一个正在创建的bean标识符放在一个“当前创建bean池”中,bean标识符在创建过程中也将一直保持在这个 池中,因此如果创建bean过程发现自己已经在“当前创建bean池”中,将抛出异常

  2. setter循环依赖:表示通过setter注入方式构成的循环依赖,对于setter注入造成的依赖是通过Spring容器提前暴露刚完成构造器注入单未完成其他步骤(如setter注入)的bean来完成的,而且只能解决单例作用域的bean循环依赖。通过提前暴露一个单例工厂方法,从而使其他bean能引用到该bean

    addSingletonFactory(beanName , new ObjectFactory(){
        public Object getObject() throws BeansException{
            return getEarlyBeanReference(beanName, mbd, bean);
        }
    })
  3. prototype范围的依赖处理:对于“prototype”作用域bean,Spring无法完成依赖注入,因为Spring容器不进行缓存“prototype”作用域的bean,因此无法提前暴露一个创建中的bean

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值