Spring源码(Ioc):BeanDefinition的资源定位过程,将bean解析封装成BeanDefinition,将BeanDefinition注册进IoC容器,依赖注入(DI).BeanPo

11 篇文章 2 订阅
2 篇文章 0 订阅

先看三张图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1、BeanDefinition的资源定位过程

正文

当我们传入一个 Spring 配置文件去实例化 FileSystemXmlApplicationContext 时,可以看一下它的构造方法都做了什么。

/**
 * 下面这 4 个构造方法都调用了第 5 个构造方法
 * @param configLocation
 * @throws BeansException
 */

// configLocation 包含了 BeanDefinition 所在的文件路径
public FileSystemXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[] {configLocation}, true, null);
}

// 可以定义多个 BeanDefinition 所在的文件路径
public FileSystemXmlApplicationContext(String... configLocations) throws BeansException {
    this(configLocations, true, null);
}

// 在定义多个 BeanDefinition 所在的文件路径 的同时,还能指定自己的双亲 IoC 容器
public FileSystemXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {
    this(configLocations, true, parent);
}

public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {
    this(configLocations, refresh, null);
}

/**
 * 如果应用直接使用 FileSystemXmlApplicationContext 进行实例化,则都会进到这个构造方法中来
 */
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
        throws BeansException {

    // 动态地确定用哪个加载器去加载我们的配置文件
    super(parent);
    // 告诉读取器 配置文件放在哪里,该方法继承于爷类 AbstractRefreshableApplicationContext
    setConfigLocations(configLocations);
    if (refresh) {
        // 容器初始化
        refresh();
    }
}


/**
 * 实例化一个 FileSystemResource 并返回,以便后续对资源的 IO 操作
 * 本方法是在其父类 DefaultResourceLoader 的 getResource 方法中被调用的,
 */
@Override
protected Resource getResourceByPath(String path) {
    if (path != null && path.startsWith("/")) {
        path = path.substring(1);
    }
    return new FileSystemResource(path);
}

看看其父类 AbstractApplicationContext 实现的 refresh() 方法,该方法就是 IoC 容器初始化的入口类

/**
 * 容器初始化的过程:BeanDefinition 的 Resource 定位、BeanDefinition 的载入、BeanDefinition 的注册。
 * BeanDefinition 的载入和 bean 的依赖注入是两个独立的过程,依赖注入一般发生在 应用第一次通过
 * getBean() 方法从容器获取 bean 时。
 *
 * 另外需要注意的是,IoC 容器有一个预实例化的配置(即,将 AbstractBeanDefinition 中的 lazyInit 属性
 * 设为 true),使用户可以对容器的初始化过程做一个微小的调控,lazyInit 设为 false 的 bean
 * 将在容器初始化时进行依赖注入,而不会等到 getBean() 方法调用时才进行
 */
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 调用容器准备刷新,获取容器的当前时间,同时给容器设置同步标识
        prepareRefresh();

        // 告诉子类启动 refreshBeanFactory() 方法,BeanDefinition 资源文件的载入从子类的 refreshBeanFactory() 方法启动开始
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 为 BeanFactory 配置容器特性,例如类加载器、事件处理器等
        prepareBeanFactory(beanFactory);

        try {
            // 为容器的某些子类指定特殊的 BeanPost 事件处理器
            postProcessBeanFactory(beanFactory);

            // 调用所有注册的 BeanFactoryPostProcessor 的 Bean
            invokeBeanFactoryPostProcessors(beanFactory);

            // 为 BeanFactory 注册 BeanPost 事件处理器.
            // BeanPostProcessor 是 Bean 后置处理器,用于监听容器触发的事件
            registerBeanPostProcessors(beanFactory);

            // 初始化信息源,和国际化相关.
            initMessageSource();

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

            // 调用子类的某些特殊 Bean 初始化方法
            onRefresh();

            // 为事件传播器注册事件监听器.
            registerListeners();

            // 初始化 Bean,并对 lazy-init 属性进行处理
            finishBeanFactoryInitialization(beanFactory);

            // 初始化容器的生命周期事件处理器,并发布容器的生命周期事件
            finishRefresh();
        }

        catch (BeansException ex) {
            // 销毁以创建的单态 Bean
            destroyBeans();

            // 取消 refresh 操作,重置容器的同步标识.
            cancelRefresh(ex);

            throw ex;
        }
    }
}

看看 obtainFreshBeanFactory() 方法,该方法告诉了子类去刷新内部的 beanFactory

/**
 * Tell the subclass to refresh the internal bean factory.
 * 告诉子类去刷新内部的 beanFactory
 */
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 自己定义了抽象的 refreshBeanFactory() 方法,具体实现交给了自己的子类
    refreshBeanFactory();
    // getBeanFactory() 也是一个抽象方法,交由子类实现
    // 看到这里是不是很容易想起 “模板方法模式”,父类在模板方法中定义好流程,定义好抽象方法
    // 具体实现交由子类完成
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
        logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}

下面看一下 AbstractRefreshableApplicationContext 中对 refreshBeanFactory() 方法的实现。FileSystemXmlApplicationContext 从上层体系的各抽象类中继承了大量的方法实现,抽象类中抽取大量公共行为进行具体实现,留下 abstract 的个性化方法交给具体的子类实现,这是一个很好的 OOP 编程设计,我们在自己编码时也可以尝试这样设计自己的类图。理清 FileSystemXmlApplicationContext 的上层体系设计,就不易被各种设计模式搞晕咯。

/**
 * 在这里完成了容器的初始化,并赋值给自己私有的 beanFactory 属性,为下一步调用做准备
 * 从父类 AbstractApplicationContext 继承的抽象方法,自己做了实现
 */
@Override
protected final void refreshBeanFactory() throws BeansException {
    // 如果已经建立了 IoC 容器,则销毁并关闭容器
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        // 创建 IoC 容器,DefaultListableBeanFactory 类实现了 ConfigurableListableBeanFactory 接口
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        // 对 IoC 容器进行定制化,如设置启动参数,开启注解的自动装配等
        customizeBeanFactory(beanFactory);
        // 载入 BeanDefinition,在当前类中只定义了抽象的 loadBeanDefinitions() 方法,具体实现 调用子类容器
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            // 给自己的属性赋值
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

AbstractXmlApplicationContext 中对 loadBeanDefinitions(DefaultListableBeanFactory beanFactory) 的实现。

/*
 * 实现了基类 AbstractRefreshableApplicationContext 的抽象方法
 */
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // DefaultListableBeanFactory 实现了 BeanDefinitionRegistry 接口,在初始化 XmlBeanDefinitionReader 时
    // 将 BeanDefinition 注册器注入该 BeanDefinition 读取器
    // 创建用于从 Xml 中读取 BeanDefinition 的读取器,并通过回调设置到 IoC 容器中去,容器使用该读取器读取 BeanDefinition 资源
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    beanDefinitionReader.setEnvironment(this.getEnvironment());
    // 为 beanDefinition 读取器设置 资源加载器,由于本类的基类 AbstractApplicationContext
    // 继承了 DefaultResourceLoader,因此,本容器自身也是一个资源加载器
    beanDefinitionReader.setResourceLoader(this);
    // 设置 SAX 解析器,SAX(simple API for XML)是另一种 XML 解析方法。相比于 DOM,SAX 速度更快,占用内存更小。
    // 它逐行扫描文档,一边扫描一边解析。相比于先将整个 XML 文件扫描近内存,再进行解析的 DOM,SAX 可以在解析文档的
    // 任意时刻停止解析,但操作也比 DOM 复杂。
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // 初始化 beanDefinition 读取器,该方法同时启用了 Xml 的校验机制
    initBeanDefinitionReader(beanDefinitionReader);
    // Bean 读取器真正实现加载的方法
    loadBeanDefinitions(beanDefinitionReader);
}

继续看 AbstractXmlApplicationContext 中 loadBeanDefinitions() 的重载方法。

/**
 * 用传进来的 XmlBeanDefinitionReader 读取器加载 Xml 文件中的 BeanDefinition
 */
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {

    /**
     * ClassPathXmlApplicationContext 与 FileSystemXmlApplicationContext 在这里的调用出现分歧,
     * 各自按不同的方式加载解析 Resource 资源,最后在具体的解析和 BeanDefinition 定位上又会殊途同归。
     */

    // 获取存放了 BeanDefinition 的所有 Resource,FileSystemXmlApplicationContext 类未对
    // getConfigResources() 进行重写,所以调用父类的,return null。
    // 而 ClassPathXmlApplicationContext 对该方法进行了重写,返回设置的值
    Resource[] configResources = getConfigResources();
    if (configResources != null) {
        // XmlBeanDefinitionReader 调用其父类 AbstractBeanDefinitionReader 的方法加载 BeanDefinition
        reader.loadBeanDefinitions(configResources);
    }
    // 调用父类 AbstractRefreshableConfigApplicationContext 的实现,
    // 优先返回 FileSystemXmlApplicationContext 构造方法中调用 setConfigLocations() 方法设置的资源
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
        // XmlBeanDefinitionReader 调用其父类 AbstractBeanDefinitionReader 的方法从配置位置加载 BeanDefinition
        reader.loadBeanDefinitions(configLocations);
    }
}

AbstractBeanDefinitionReader 中对 loadBeanDefinitions 方法的各种重载及调用。

/**
 * loadBeanDefinitions() 方法的重载方法之一,调用了另一个重载方法 loadBeanDefinitions(String)
 */
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
    Assert.notNull(locations, "Location array must not be null");
    // 计数器,统计加载了多少个BeanDefinition
    int counter = 0;
    for (String location : locations) {
        counter += loadBeanDefinitions(location);
    }
    return counter;
}

/**
 * 重载方法之一,调用了下面的 loadBeanDefinitions(String, Set<Resource>) 方法
 */
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(location, null);
}

/**
 * 获取在 IoC 容器初始化过程中设置的资源加载器
 */
public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
    // 在实例化 XmlBeanDefinitionReader 后 IoC 容器将自己注入进该读取器作为 resourceLoader 属性
    ResourceLoader resourceLoader = getResourceLoader();
    if (resourceLoader == null) {
        throw new BeanDefinitionStoreException(
                "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
    }

    if (resourceLoader instanceof ResourcePatternResolver) {
        try {
            // 将指定位置的 BeanDefinition 资源文件解析为 IoC 容器封装的资源
            // 加载多个指定位置的 BeanDefinition 资源文件
            Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
            // 委派调用其子类 XmlBeanDefinitionReader 的方法,实现加载功能
            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 {
        /**
         * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         * AbstractApplicationContext 继承了 DefaultResourceLoader,所以 AbstractApplicationContext
         * 及其子类都会调用 DefaultResourceLoader 中的实现,将指定位置的资源文件解析为 Resource,
         * 至此完成了对 BeanDefinition 的资源定位
         * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         */
        Resource resource = resourceLoader.getResource(location);
        // 从 resource 中加载 BeanDefinition,loadCount 为加载的 BeanDefinition 个数
        // 该 loadBeanDefinitions() 方法来自其实现的 BeanDefinitionReader 接口,
        // 且本类是一个抽象类,并未对该方法进行实现。而是交由子类进行实现,如果是用 xml 文件进行
        // IoC 容器的初始化,则调用 XmlBeanDefinitionReader 中的实现
        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 的 getResource() 方法有多种实现,看清 FileSystemXmlApplicationContext 的继承体系就可以明确,其走的是 DefaultResourceLoader 中的实现。

/**
 * 获取 Resource 的具体实现方法
 */
public Resource getResource(String location) {
    Assert.notNull(location, "Location must not be null");
    // 如果 location 是类路径的方式,返回 ClassPathResource 类型的文件资源对象
    if (location.startsWith(CLASSPATH_URL_PREFIX)) {
        return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
    }
    else {
        try {
            // 如果是 URL 方式,返回 UrlResource 类型的文件资源对象,
            // 否则将抛出的异常进入 catch 代码块,返回另一种资源对象
            URL url = new URL(location);
            return new UrlResource(url);
        }
        catch (MalformedURLException ex) {
            // 如果既不是 classpath 标识,又不是 URL 标识的 Resource 定位,则调用容器本身的
            // getResourceByPath() 方法获取 Resource。根据实例化的子类对象,调用其子类对象中
            // 重写的此方法,如 FileSystemXmlApplicationContext 子类中对此方法的重写
            return getResourceByPath(location);
        }
    }
}

其中的 getResourceByPath(location) 方法的实现则是在 FileSystemXmlApplicationContext 中完成的。

/**
 * 实例化一个 FileSystemResource 并返回,以便后续对资源的 IO 操作
 * 本方法是在 DefaultResourceLoader 的 getResource() 方法中被调用的,
 */
@Override
protected Resource getResourceByPath(String path) {
    if (path != null && path.startsWith("/")) {
        path = path.substring(1);
    }
    return new FileSystemResource(path);
}

至此,我们可以看到,FileSystemXmlApplicationContext 的 getResourceByPath() 方法返回了一个 FileSystemResource 对象,接下来 spring 就可以对这个对象进行相关的 I/O 操作,进行 BeanDefinition 的读取和载入了。

2、将bean解析封装成BeanDefinition

正文

首先看一下 AbstractRefreshableApplicationContext 的 refreshBeanFactory() 方法,这是一个模板方法,其中调用的 loadBeanDefinitions() 方法是一个抽象方法,交由子类实现。

/**
 * 在这里完成了容器的初始化,并赋值给自己私有的 beanFactory 属性,为下一步调用做准备
 * 从父类 AbstractApplicationContext 继承的抽象方法,自己做了实现
 */
@Override
protected final void refreshBeanFactory() throws BeansException {
    // 如果已经建立了 IoC 容器,则销毁并关闭容器
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        // 创建 IoC 容器,DefaultListableBeanFactory 实现了 ConfigurableListableBeanFactory 接口
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        // 对 IoC 容器进行定制化,如设置启动参数,开启注解的自动装配等
        customizeBeanFactory(beanFactory);
        // 载入 BeanDefinition,当前类中只定义了抽象的 loadBeanDefinitions() 方法,具体的实现调用子类容器
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            // 给自己的属性赋值
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

下面看一下 AbstractRefreshableApplicationContext 的子类 AbstractXmlApplicationContext 对 loadBeanDefinitions() 方法的实现。

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // DefaultListableBeanFactory 实现了 BeanDefinitionRegistry 接口,所以在初始化 XmlBeanDefinitionReader 时
    // 将该 beanFactory 传入 XmlBeanDefinitionReader 的构造方法中。
    // 从名字也能看出来它的功能,这是一个用于从 .xml文件 中读取 BeanDefinition 的读取器
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    beanDefinitionReader.setEnvironment(this.getEnvironment());
    // 为 beanDefinition 读取器设置 资源加载器,由于本类的基类 AbstractApplicationContext
    // 继承了 DefaultResourceLoader,因此,本容器自身也是一个资源加载器
    beanDefinitionReader.setResourceLoader(this);
    // 为 beanDefinitionReader 设置用于解析的 SAX 实例解析器,SAX(simple API for XML)是另一种XML解析方法。
    // 相比于DOM,SAX速度更快,占用内存更小。它逐行扫描文档,一边扫描一边解析。相比于先将整个XML文件扫描进内存,
    // 再进行解析的DOM,SAX可以在解析文档的任意时刻停止解析,但操作也比DOM复杂。
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // 初始化 beanDefinition 读取器,该方法同时启用了 XML 的校验机制
    initBeanDefinitionReader(beanDefinitionReader);
    // 用传进来的 XmlBeanDefinitionReader 读取器读取 .xml 文件中配置的 bean
    loadBeanDefinitions(beanDefinitionReader);
}

接着看一下上面最后一个调用的方法 loadBeanDefinitions(XmlBeanDefinitionReader reader)。

/**
 * 读取并解析 .xml 文件中配置的 bean,然后封装成 BeanDefinition 对象
 */
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    /**
     * ClassPathXmlApplicationContext 与 FileSystemXmlApplicationContext
     * 在这里的调用出现分歧,各自按不同的方式加载解析 Resource 资源
     * 最后在具体的解析和 BeanDefinition 定位上又会殊途同归
     */

    // 获取存放了 BeanDefinition 的所有 Resource,FileSystemXmlApplicationContext 中未对
    // getConfigResources() 进行重写,所以调用父类的,return null。
    // 而 ClassPathXmlApplicationContext 对该方法进行了重写,返回设置的值
    Resource[] configResources = getConfigResources();
    if (configResources != null) {
        // 这里调用的是其父类 AbstractBeanDefinitionReader 中的方法,解析加载 BeanDefinition对象
        reader.loadBeanDefinitions(configResources);
    }
    // 调用其父类 AbstractRefreshableConfigApplicationContext 中的实现,优先返回
    // FileSystemXmlApplicationContext 构造方法中调用 setConfigLocations() 方法设置的资源路径
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
        // 这里调用其父类 AbstractBeanDefinitionReader 的方法从配置位置加载 BeanDefinition
        reader.loadBeanDefinitions(configLocations);
    }
}

AbstractBeanDefinitionReader 对 loadBeanDefinitions() 方法的三重重载。

/**
 * loadBeanDefinitions() 方法的重载方法之一,调用了另一个重载方法 loadBeanDefinitions(String location)
 */
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;
}

/**
 * 重载方法之一,调用了下面的 loadBeanDefinitions(String location, Set<Resource> actualResources) 方法
 */
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(location, null);
}

/**
 * 获取在 IoC 容器初始化过程中设置的资源加载器
 */
public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
    // 在实例化 XmlBeanDefinitionReader 时 曾将 IoC 容器注入该对象,作为 resourceLoader 属性
    ResourceLoader resourceLoader = getResourceLoader();
    if (resourceLoader == null) {
        throw new BeanDefinitionStoreException(
                "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
    }

    if (resourceLoader instanceof ResourcePatternResolver) {
        try {
            // 将指定位置的 bean 配置文件解析为 BeanDefinition 对象
            // 加载多个指定位置的 BeanDefinition 资源
            Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
            // 调用其子类 XmlBeanDefinitionReader 的方法,实现加载功能
            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 {
        /**
         * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         * AbstractApplicationContext 继承了 DefaultResourceLoader,所以 AbstractApplicationContext
         * 及其子类都可以调用 DefaultResourceLoader 中的方法,将指定位置的资源文件解析为 Resource,
         * 至此完成了对 BeanDefinition 的资源定位
         * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         */
        Resource resource = resourceLoader.getResource(location);
        // 从 resource 中加载 BeanDefinition,loadCount 为加载的 BeanDefinition 个数
        // 该 loadBeanDefinitions() 方法来自其 implements 的 BeanDefinitionReader 接口,
        // 且本类是一个抽象类,并未对该方法进行实现。而是交由子类进行实现,如果是用 xml 文件进行
        // IoC 容器初始化的,则调用 XmlBeanDefinitionReader 中的实现
        int loadCount = loadBeanDefinitions(resource);
        if (actualResources != null) {
            actualResources.add(resource);
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
        }
        return loadCount;
    }
}

XmlBeanDefinitionReader 读取器中的方法执行流,按代码的先后顺序。

/**
 * XmlBeanDefinitionReader 加载资源的入口方法
 */
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    // 调用本类的重载方法,通过 new EncodedResource(resource) 获得的 EncodedResource 对象
    // 能够将资源与读取资源所需的编码组合在一起
    return loadBeanDefinitions(new EncodedResource(resource));
}

/**
 * 通过 encodedResource 进行资源解析,encodedResource 对象持有 resource 对象和 encoding 编码格式
 */
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!");
    }
    try {
        // 从 resource 中获取输入流,对 resource 中的内容进行读取
        InputStream inputStream = encodedResource.getResource().getInputStream();
        try {
            // 实例化一个"XML 实体的单个输入源",将 inputStream 作为自己的属性
            InputSource inputSource = new InputSource(inputStream);
            // 如果 encodedResource 中的 encoding 属性不为空,就为 inputSource 设置读取 XML 的编码格式
            if (encodedResource.getEncoding() != null) {
                inputSource.setEncoding(encodedResource.getEncoding());
            }
            // 这里是具体的读取过程
            return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
        }
        finally {
            // 关闭 IO 流
            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 文件中解析 bean,封装成 BeanDefinition 对象的具体实现
 */
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
        throws BeanDefinitionStoreException {
    try {
        int validationMode = getValidationModeForResource(resource);
        // 通过 documentLoader 获取 XML 文件的 Document 对象
        Document doc = this.documentLoader.loadDocument(
                inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware());
        // 启动对 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 对配置文件中 bean 元素的语义定义,将 bean 元素 解析成 BeanDefinition 对象
 */
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    // 得到 BeanDefinitionDocumentReader,将 xml 中配置的 bean 解析成 BeanDefinition 对象
    // BeanDefinitionDocumentReader 只是个接口,这里实际上是一个 DefaultBeanDefinitionDocumentReader 对象
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    documentReader.setEnvironment(this.getEnvironment());
    // 获得容器中注册的 bean 数量
    int countBefore = getRegistry().getBeanDefinitionCount();
    // 解析过程入口
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    // 统计解析的 Bean 数量
    return getRegistry().getBeanDefinitionCount() - countBefore;
}

文档解析器 DefaultBeanDefinitionDocumentReader 对配置文件中元素的解析。

// 根据 Spring 对 Bean 的定义规则进行解析
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    // 获得 XML 描述符
    this.readerContext = readerContext;
    logger.debug("Loading bean definitions");
    // 获得 Document 的根元素
    Element root = doc.getDocumentElement();
    // 解析的具体实现
    doRegisterBeanDefinitions(root);
}


/**
 * 依次注册 BeanDefinition,使用给定的根元素
 */
protected void doRegisterBeanDefinitions(Element root) {
    String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
    if (StringUtils.hasText(profileSpec)) {
        Assert.state(this.environment != null, "Environment must be set for evaluating profiles");
        String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
        if (!this.environment.acceptsProfiles(specifiedProfiles)) {
            return;
        }
    }

    // 具体的解析过程由 BeanDefinitionParserDelegate 实现,
    // BeanDefinitionParserDelegate中定义了用于解析 bean 的各种属性及方法
    BeanDefinitionParserDelegate parent = this.delegate;
    this.delegate = createDelegate(this.readerContext, root, parent);


    // 前置解析处理,可以在解析 bean 之前进行自定义的解析,增强解析的可扩展性
    preProcessXml(root);
    // 从 Document 的根元素开始进行 Bean 定义的 Document 对象
    parseBeanDefinitions(root, this.delegate);
    // 后置解析处理,可以在解析 bean 之后进行自定义的解析,增加解析的可扩展性
    postProcessXml(root);

    this.delegate = parent;
}

/**
 * 根据 Spring 的 bean解析规则,从 Document 的根元素开始进行解析
 */
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    // 根节点 root 是否使用了 Spring 默认的 XML 命名空间
    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;
                // 如果 ele 定义的 Document 的元素节点使用的是 Spring 默认的 XML 命名空间
                if (delegate.isDefaultNamespace(ele)) {
                    // 使用 Spring 的 bean解析规则 解析元素节点
                    parseDefaultElement(ele, delegate);
                }
                else {
                    // 若没有使用 Spring 默认的 XML 命名空间,则使用用户自定义的解析规则解析元素节点
                    delegate.parseCustomElement(ele);
                }
            }
        }
    }
    else {
        // 若 Document 的根节点没有使用 Spring 默认的命名空间,则使用用户自定义的解析规则
        // 解析 Document 根节点
        delegate.parseCustomElement(root);
    }
}

/**
 * 使用 Spring 的 bean解析规则 解析 Spring元素节点
 */
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);
    }
    // 若元素节点既不是 <Import> 也不是 <Alias>,即普通的 <Bean> 元素,
    // 则按照 Spring 的 bean解析规则 解析元素
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
        processBeanDefinition(ele, delegate);
    }
    // 如果被解析的元素是 beans,则递归调用 doRegisterBeanDefinitions(Element root) 方法进行解析
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
        doRegisterBeanDefinitions(ele);
    }
}

/**
 * 解析 <import> 元素
 */
protected void importBeanDefinitionResource(Element ele) {
    // 获取给定的导入元素的 location 属性
    String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
    // 如果导入元素的 location 属性值为空,则没有导入任何资源,直接返回
    if (!StringUtils.hasText(location)) {
        getReaderContext().error("Resource location must not be empty", ele);
        return;
    }

    // 使用系统变量值解析 location 属性值
    location = environment.resolveRequiredPlaceholders(location);

    Set<Resource> actualResources = new LinkedHashSet<Resource>(4);

    // 标识给定的 <Import> 元素的 location 是否是绝对路径
    boolean absoluteLocation = false;
    try {
        absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();
    }
    catch (URISyntaxException ex) {
    }

    if (absoluteLocation) {
        try {
            // 使用资源读取器加载给定路径的 bean
            int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
            if (logger.isDebugEnabled()) {
                logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]");
            }
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error(
                    "Failed to import bean definitions from URL location [" + location + "]", ele, ex);
        }
    }
    else {
        // 给定的 <import> 元素的 location 是相对路径
        try {
            int importCount;
            // 将给定 <import> 元素的 location 封装为相对路径资源
            Resource relativeResource = getReaderContext().getResource().createRelative(location);
            // 封装的相对路径资源存在
            if (relativeResource.exists()) {
                // 使用资源读取器加载 bean
                importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource);
                actualResources.add(relativeResource);
            }
            // 封装的相对路径资源不存在
            else {
                // 获取 Spring IOC 容器资源读取器的基本路径
                String baseLocation = getReaderContext().getResource().getURL().toString();
                // 根据 Spring IoC 容器资源读取器的基本路径加载给定导入路径的资源
                importCount = getReaderContext().getReader().loadBeanDefinitions(
                        StringUtils.applyRelativePath(baseLocation, location), actualResources);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]");
            }
        }
        catch (IOException ex) {
            getReaderContext().error("Failed to resolve current resource location", ele, ex);
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]",
                    ele, ex);
        }
    }
    Resource[] actResArray = actualResources.toArray(new Resource[actualResources.size()]);
    // 在解析完 <Import> 元素之后,发送容器导入其他资源处理完成事件
    getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
}

/**
 * 解析 <Alias> 元素
 */
protected void processAliasRegistration(Element ele) {
    // 获取 <Alias> 元素中的 name 属性值
    String name = ele.getAttribute(NAME_ATTRIBUTE);
    // 获取 <Alias> 元素中的 alias 属性值
    String alias = ele.getAttribute(ALIAS_ATTRIBUTE);
    boolean valid = true;
    // 若 <alias> 元素的 name 属性值为空
    if (!StringUtils.hasText(name)) {
        getReaderContext().error("Name must not be empty", ele);
        valid = false;
    }
    // 若 <alias> 元素的 alias 属性值为空
    if (!StringUtils.hasText(alias)) {
        getReaderContext().error("Alias must not be empty", ele);
        valid = false;
    }
    if (valid) {
        try {
            // 向容器的资源读取器 注册别名
            getReaderContext().getRegistry().registerAlias(name, alias);
        }
        catch (Exception ex) {
            getReaderContext().error("Failed to register alias '" + alias +
                    "' for bean with name '" + name + "'", ele, ex);
        }
        // 在解析完 <Alias> 元素之后,向容器发送别名处理完成事件
        getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));
    }
}

/**
 * 解析 bean 元素
 */
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {

    // BeanDefinitionHolder 是对 BeanDefinition 的进一步封装,持有一个 BeanDefinition 对象 及其对应
    // 的 beanName、aliases别名。对 <Bean> 元素的解析由 BeanDefinitionParserDelegate 实现
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        // 对 bdHolder 进行包装处理
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
            /**
             * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
             * 向 Spring IoC 容器注册解析完成的 BeanDefinition对象,这是 BeanDefinition 向 IoC 容器注册的入口
             * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
             */
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to register bean definition with name '" +
                    bdHolder.getBeanName() + "'", ele, ex);
        }
        // 在完成向 Spring IOC 容器注册 BeanDefinition对象 之后,发送注册事件
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

看一下 BeanDefinitionParserDelegate 中对 bean 元素的详细解析过程。

/**
 * 解析 <bean> 元素的入口
 */
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
    return parseBeanDefinitionElement(ele, null);
}

/**
 * 解析 <bean> 元素,这个方法中主要处理 <bean> 元素的 id、name 和 alias 属性
 */
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
    // 获取 <bean> 元素中的 id 属性值
    String id = ele.getAttribute(ID_ATTRIBUTE);

    // 获取 <bean> 元素中的 name 属性值
    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

    // 获取 <bean> 元素中的 alias 属性值
    List<String> aliases = new ArrayList<String>();

    // 将 <bean> 元素中的所有 name 属性值存放到别名中
    if (StringUtils.hasLength(nameAttr)) {
        String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
        aliases.addAll(Arrays.asList(nameArr));
    }

    String beanName = id;
    // 如果 <bean> 元素中没有配置 id 属性,则将 别名alias 中的第一个值赋值给 beanName
    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");
        }
    }

    // 检查 <bean> 元素所配置的 id 或者 name 的唯一性
    // 元素中是否包含子 <bean> 元素
    if (containingBean == null) {
        // 检查 <bean> 元素所配置的 id、name 或者 别名alias 是否重复
        checkNameUniqueness(beanName, aliases, ele);
    }

    // 将 <bean> 元素解析成 BeanDefinition对象
    AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
    if (beanDefinition != null) {
        if (!StringUtils.hasText(beanName)) {
            try {
                // 如果 <bean> 元素中没有配置 id、name 或者 alias,且没有包含子元素
                if (containingBean != null) {
                    // 为解析的 BeanDefinition 生成一个唯一的 beanName
                    beanName = BeanDefinitionReaderUtils.generateBeanName(
                            beanDefinition, this.readerContext.getRegistry(), true);
                }
                else {
                    beanName = this.readerContext.generateBeanName(beanDefinition);
                    // 在别名集合 aliases 中添加 bean 的类名
                    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);
    }
    // 当解析出错时,返回 null
    return null;
}

/**
 * 详细对 <bean> 元素中的其他属性进行解析,上面的方法中已经对 bean 的 id、name 及 alias 属性进行了处理
 */
public AbstractBeanDefinition parseBeanDefinitionElement(
        Element ele, String beanName, BeanDefinition containingBean) {

    // 记录解析的 <bean>
    this.parseState.push(new BeanEntry(beanName));

    // 这里只读取 <bean> 元素中配置的 class 名字,然后载入到 BeanDefinition 中去
    // 只是记录配置的 class 名字,不做实例化,对象的实例化在 getBean() 时发生
    String className = null;
    if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
        className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
    }

    try {
        String parent = null;
        // 如果 <bean> 元素中配置了 parent 属性,则获取 parent 属性的值
        if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
            parent = ele.getAttribute(PARENT_ATTRIBUTE);
        }

        // 根据 <bean> 元素配置的 class 名称和 parent 属性值创建 BeanDefinition
        AbstractBeanDefinition bd = createBeanDefinition(className, parent);

        // 对当前的 <bean> 元素中配置的一些属性进行解析和设置,如配置的单例 (singleton) 属性等
        parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
        // 为 BeanDefinition对象 注入 description属性值
        bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

        // 解析 <bean> 元素中的 meta 属性
        parseMetaElements(ele, bd);
        // 解析 <bean> 元素中的 lookup-method 属性
        parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
        // 解析 <bean> 元素中的 replaced-method 属性
        parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

        // 解析 <bean> 元素的构造方法
        parseConstructorArgElements(ele, bd);
        // 解析 <bean> 元素中的所有 <property> 元素
        parsePropertyElements(ele, bd);
        // 解析 <bean> 元素的 qualifier 属性
        parseQualifierElements(ele, bd);

        // 为当前BeanDefinition对象 设置所需的资源和依赖对象
        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();
    }
    // 解析 <bean> 元素出错时,返回 null
    return null;
}

对 bean 的部分子元素进行解析的具体实现。

/**
 * 解析 <bean> 元素中所有的 <property> 子元素
 */
public void parsePropertyElements(Element beanEle, BeanDefinition bd) {
    // 获取对应 <bean> 元素中所有的 <property> 子元素,逐一解析
    NodeList nl = beanEle.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
        Node node = nl.item(i);
        // 对 <property> 子元素进行详细解析
        if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {
            parsePropertyElement((Element) node, bd);
        }
    }
}

/**
 * 详细解析 <property> 元素
 */
public void parsePropertyElement(Element ele, BeanDefinition bd) {
    // 获取 <property> 元素的名字
    String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
    if (!StringUtils.hasLength(propertyName)) {
        error("Tag 'property' must have a 'name' attribute", ele);
        return;
    }
    this.parseState.push(new PropertyEntry(propertyName));
    try {
        // 如果一个 Bean 中已经有同名的 property 存在,则不进行解析,直接返回。
        // 即如果在同一个 Bean 中配置同名的 property,则只有第一个起作用
        if (bd.getPropertyValues().contains(propertyName)) {
            error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
            return;
        }
        // 解析获取 propertyName 对应的 value值,propertyName 及其 value值会被封装到
        // PropertyValue 对象中,然后 set 到 BeanDefinition对象中去
        Object val = parsePropertyValue(ele, bd, propertyName);
        // 根据 property 的 名字propertyName 和 值val 创建 PropertyValue实例
        PropertyValue pv = new PropertyValue(propertyName, val);
        // 解析 <meta> 元素
        parseMetaElements(ele, pv);
        pv.setSource(extractSource(ele));
        // 为当前的 BeanDefinition对象设置 propertyValues 属性值
        bd.getPropertyValues().addPropertyValue(pv);
    }
    finally {
        this.parseState.pop();
    }
}

/**
 * 解析获取 <property> 元素的属性值 value
 */
public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {
    String elementName = (propertyName != null) ?
                    "<property> element for property '" + propertyName + "'" :
                    "<constructor-arg> element";

    // 获取 <property> 的所有子元素,只能是其中一种类型:ref,value,list 等
    NodeList nl = ele.getChildNodes();
    Element subElement = null;
    for (int i = 0; i < nl.getLength(); i++) {
        Node node = nl.item(i);
        // 如果子元素不是 description 和 meta 属性
        if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT) &&
                !nodeNameEquals(node, META_ELEMENT)) {
            // Child element is what we're looking for.
            if (subElement != null) {
                error(elementName + " must not contain more than one sub-element", ele);
            }
            else {// 当前 <property> 元素包含有子元素
                subElement = (Element) node;
            }
        }
    }

    // 判断 property 的属性值是 ref 还是 value,不允许既是 ref 又是 value
    boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
    boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
    if ((hasRefAttribute && hasValueAttribute) ||
            ((hasRefAttribute || hasValueAttribute) && subElement != null)) {
        error(elementName +
                " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
    }

    // 如果属性是 ref,创建一个 ref 的数据对象 RuntimeBeanReference
    // 这个对象封装了 ref 信息
    if (hasRefAttribute) {
        String refName = ele.getAttribute(REF_ATTRIBUTE);
        if (!StringUtils.hasText(refName)) {
            error(elementName + " contains empty 'ref' attribute", ele);
        }
        // 一个指向运行时所依赖对象的引用
        RuntimeBeanReference ref = new RuntimeBeanReference(refName);
        // 设置这个 ref 的数据对象是被当前的 property 对象所引用
        ref.setSource(extractSource(ele));
        return ref;
    }
    // 如果属性是 value,创建一个 value 的数据对象 TypedStringValue
    // 这个对象封装了 value 信息
    else if (hasValueAttribute) {
        // 一个持有 String 类型值的对象
        TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));
        // 设置这个 value 数据对象是被当前的 property 对象所引用
        valueHolder.setSource(extractSource(ele));
        return valueHolder;
    }
    // 如果当前 <property> 元素还有子元素
    else if (subElement != null) {
        // 解析 <property> 的子元素
        return parsePropertySubElement(subElement, bd);
    }
    else {
        // propery 属性中既不是 ref,也不是 value 属性,解析出错返回 null
        error(elementName + " must specify a ref or value", ele);
        return null;
    }
}

/**
 * 解析 <property> 元素中 ref,value 或者集合等子元素
 */
public Object parsePropertySubElement(Element ele, BeanDefinition bd) {
    return parsePropertySubElement(ele, bd, null);
}

public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultValueType) {
    // 如果 <property> 没有使用 Spring 默认的命名空间,则使用用户自定义的规则解析
    // 内嵌元素
    if (!isDefaultNamespace(ele)) {
        return parseNestedCustomElement(ele, bd);
    }
    // 如果子元素是 bean,则使用解析 <Bean> 元素的方法解析
    else if (nodeNameEquals(ele, BEAN_ELEMENT)) {
        BeanDefinitionHolder nestedBd = parseBeanDefinitionElement(ele, bd);
        if (nestedBd != null) {
            nestedBd = decorateBeanDefinitionIfRequired(ele, nestedBd, bd);
        }
        return nestedBd;
    }
    // 如果子元素是 ref,ref 中只能有以下 3 个属性:bean、local、parent
    else if (nodeNameEquals(ele, REF_ELEMENT)) {
        // 获取 <property> 元素中的 bean 属性值,引用其他解析的 Bean 的名称
        // 可以不再同一个 Spring 配置文件中,具体请参考 Spring 对 ref 的配置规则
        String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE);
        boolean toParent = false;
        if (!StringUtils.hasLength(refName)) {
            // 获取 <property> 元素中的 local 属性值,引用同一个 Xml 文件中配置
            // 的 Bean 的 id,local 和 ref 不同,local 只能引用同一个配置文件中的 Bean
            refName = ele.getAttribute(LOCAL_REF_ATTRIBUTE);
            if (!StringUtils.hasLength(refName)) {
                // 获取 <property> 元素中 parent 属性值,引用父级容器中的 Bean
                refName = ele.getAttribute(PARENT_REF_ATTRIBUTE);
                toParent = true;

                if (!StringUtils.hasLength(refName)) {
                    error("'bean', 'local' or 'parent' is required for <ref> element", ele);
                    return null;
                }
            }
        }

        // 没有配置 ref 的目标属性值
        if (!StringUtils.hasText(refName)) {
            error("<ref> element contains empty target attribute", ele);
            return null;
        }
        // 创建 ref 类型数据,指向被引用的对象
        RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent);
        // 设置引用类型值是被当前子元素所引用
        ref.setSource(extractSource(ele));
        return ref;
    }
    // 如果子元素是 <idref>,使用解析 ref 元素的方法解析
    else if (nodeNameEquals(ele, IDREF_ELEMENT)) {
        return parseIdRefElement(ele);
    }
    // 如果子元素是 <value>,使用解析 value 元素的方法解析
    else if (nodeNameEquals(ele, VALUE_ELEMENT)) {
        return parseValueElement(ele, defaultValueType);
    }
    //如果子元素是 null,为 <property> 设置一个封装 null 值的字符串数据
    else if (nodeNameEquals(ele, NULL_ELEMENT)) {
        TypedStringValue nullHolder = new TypedStringValue(null);
        nullHolder.setSource(extractSource(ele));
        return nullHolder;
    }
    // 如果子元素是 <array>,使用解析 array 集合子元素的方法解析
    else if (nodeNameEquals(ele, ARRAY_ELEMENT)) {
        return parseArrayElement(ele, bd);
    }
    // 如果子元素是 <list>,使用解析 list 集合子元素的方法解析
    else if (nodeNameEquals(ele, LIST_ELEMENT)) {
        return parseListElement(ele, bd);
    }
    // 如果子元素是 <set>,使用解析 set 集合子元素的方法解析
    else if (nodeNameEquals(ele, SET_ELEMENT)) {
        return parseSetElement(ele, bd);
    }
    // 如果子元素是 <map>,使用解析 map 集合子元素的方法解析
    else if (nodeNameEquals(ele, MAP_ELEMENT)) {
        return parseMapElement(ele, bd);
    }
    // 如果子元素是 <props>,使用解析 props 集合子元素的方法解析
    else if (nodeNameEquals(ele, PROPS_ELEMENT)) {
        return parsePropsElement(ele);
    }
    // 既不是 ref,又不是 value,也不是集合,则子元素配置错误,返回 null
    else {
        error("Unknown property sub-element: [" + ele.getNodeName() + "]", ele);
        return null;
    }
}

/**
 * 解析 <list> 集合子元素
 */
public List parseListElement(Element collectionEle, BeanDefinition bd) {
    // 获取 <list> 元素中的 value-type 属性,即获取集合元素的数据类型
    String defaultElementType = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
    // 获取 <list> 集合元素中的所有子节点
    NodeList nl = collectionEle.getChildNodes();
    // Spring 中将 List 封装为 ManagedList
    ManagedList<Object> target = new ManagedList<Object>(nl.getLength());
    target.setSource(extractSource(collectionEle));
    // 设置集合目标数据类型
    target.setElementTypeName(defaultElementType);
    target.setMergeEnabled(parseMergeAttribute(collectionEle));
    // 具体的 <list> 元素解析
    parseCollectionElements(nl, target, bd, defaultElementType);
    return target;
}

/**
 * 具体解析 <list> 集合元素,<array>、<list> 和 <set> 都使用该方法解析
 */
protected void parseCollectionElements(NodeList elementNodes, Collection<Object> target,
        BeanDefinition bd, String defaultElementType) {

    // 遍历集合所有节点
    for (int i = 0; i < elementNodes.getLength(); i++) {
        Node node = elementNodes.item(i);
        // 节点不是 description 节点
        if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT)) {
            // 将解析的元素加入集合中,递归调用下一个子元素
            target.add(parsePropertySubElement((Element) node, bd, defaultElementType));
        }
    }
}

经过这样逐层地解析,我们在配置文件中定义的 bean 就被整个解析成了 IoC 容器能够装载和使用的 BeanDefinition 对象,这种数据结构可以让 IoC 容器执行索引、查询等操作。经过上述解析,接下来我们就可以将得到的 BeanDefinition 对象 注册到 IoC 容器中咯。

3、将BeanDefinition注册进IoC容器

正文

回过头看一下前面在 DefaultBeanDefinitionDocumentReader 中实现的 processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) 方法。

/**
 * 将 .xml 文件中的元素解析成 BeanDefinition对象,并注册到 IoC容器 中
 */
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {

    // BeanDefinitionHolder 是对 BeanDefinition 的进一步封装,它持有一个 BeanDefinition 对象 及其对应
    // 的 beanName、aliases别名。
    // 对 Document 对象中 <Bean> 元素的解析由 BeanDefinitionParserDelegate 实现
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        // 对 bdHolder 进行包装处理
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
            /**
             * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
             * 向 IoC 容器注册解析完成的 BeanDefinition对象,这是 BeanDefinition 向 IoC 容器注册的入口
             * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
             */
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to register bean definition with name '" +
                    bdHolder.getBeanName() + "'", ele, ex);
        }
        // 在完成向 IOC容器 注册 BeanDefinition对象 之后,发送注册事件
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

接着看一下 BeanDefinitionReaderUtils 的 registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) 方法。

/**
 * 将解析到的 BeanDefinition对象 注册到 IoC容器
 */
public static void registerBeanDefinition(
        BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
        throws BeanDefinitionStoreException {

    // 获取解析的 <bean>元素 的名称 beanName
    String beanName = definitionHolder.getBeanName();
    /**
     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     * 开始向 IoC容器 注册 BeanDefinition对象
     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     */
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // 如果解析的 <bean>元素 有别名alias,向容器中注册别名
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String aliase : aliases) {
            registry.registerAlias(beanName, aliase);
        }
    }
}

BeanDefinitionRegistry 中的 registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 方法在 DefaultListableBeanFactory 实现类中的具体实现。

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

    /** 按注册顺序排列的 beanDefinition名称列表(即 beanName)  */
    private final List<String> beanDefinitionNames = new ArrayList<String>();

    /** IoC容器 的实际体现,key --> beanName,value --> BeanDefinition对象 */
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);

    /**
     * 向 IoC容器 注册解析的 beanName 和 BeanDefinition对象
     */
    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");

        // 校验解析的 BeanDefiniton对象
        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition) beanDefinition).validate();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Validation of bean definition failed", ex);
            }
        }

        // 注册的过程中需要线程同步,以保证数据的一致性
        synchronized (this.beanDefinitionMap) {
            Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);

            // 检查是否有同名(beanName)的 BeanDefinition 存在于 IoC容器 中,如果已经存在,且不允许覆盖
            // 已注册的 BeanDefinition,则抛出注册异常,allowBeanDefinitionOverriding 默认为 true
            if (oldBeanDefinition != null) {
                if (!this.allowBeanDefinitionOverriding) {
                    throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                            "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
                            "': There is already [" + oldBeanDefinition + "] bound.");
                }
                // 如果允许覆盖同名的 bean,后注册的会覆盖先注册的
                else {
                    if (this.logger.isInfoEnabled()) {
                        this.logger.info("Overriding bean definition for bean '" + beanName +
                                "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                    }
                }
            }
            // 若该 beanName 在 IoC容器 中尚未注册,将其注册到 IoC容器中,
            else {
                // 将 beanName 注册到 beanDefinitionNames列表
                this.beanDefinitionNames.add(beanName);
                this.frozenBeanDefinitionNames = null;
            }
            // beanDefinitionMap 是 IoC容器 的最主要体现,他是一个 ConcurrentHashMap,
            // 直接存储了 bean的唯一标识 beanName,及其对应的 BeanDefinition对象
            this.beanDefinitionMap.put(beanName, beanDefinition);
        }
        // 重置所有已经注册过的 BeanDefinition 的缓存
        resetBeanDefinition(beanName);
    }
}

4、依赖注入(DI)

正文

首先看一下 AbstractBeanFactory 中的 getBean() 系列方法及 doGetBean() 具体实现。

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

    //---------------------------------------------------------------------
    // BeanFactory 接口的实现,下列的 getBean() 方法不论是哪种重载,最后都会走
    // doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) 的具体实现
    //---------------------------------------------------------------------

    // 获取 IoC容器 中指定名称的 bean
    public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }

    // 获取 IoC容器 中指定名称和类型的 bean
    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        return doGetBean(name, requiredType, null, false);
    }

    // 获取 IoC容器 中指定名称和参数的 bean
    public Object getBean(String name, Object... args) throws BeansException {
        return doGetBean(name, null, args, false);
    }

    // 获取 IoC容器 中指定名称、类型和参数的 bean
    public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
        return doGetBean(name, requiredType, args, false);
    }

    // 真正实现向 IoC容器 获取 bean 的功能,也是触发 依赖注入(DI) 的地方
    @SuppressWarnings("unchecked")
    protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args,
            boolean typeCheckOnly) throws BeansException {

        // 根据用户给定的名称(也可能是别名alias) 获取 IoC容器 中与 BeanDefinition 唯一对应的 beanName
        final String beanName = transformedBeanName(name);
        Object bean;

        // 根据 beanName 查看缓存中是否有已实例化的 单例bean,对于 单例bean,整个 IoC容器 只创建一次
        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 + "'");
                }
            }
            // 获取给定 bean 的实例对象,主要是完成 FactoryBean 的相关处理
            // 注意:BeanFactory 是一个 IoC容器,它保存了 bean 的基本配置信息。
            // 而 FactoryBean 是 IoC容器 中一种特殊的 bean,它能够实例化 bean对象,注意两者之间的区别
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        // 如果应用程序要获取的 bean 还未创建
        else {
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // 获取当前容器的父容器
            BeanFactory parentBeanFactory = getParentBeanFactory();
            // 如果当前容器中没有指定的 bean,且当前容器的父容器不为空
            // 则从父容器中去找,如果父容器也没有,则沿着当前容器的继承体系一直向上查找
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // 根据用户传入的 name(有可能是别名alias),获取唯一标识的 beanName
                String nameToLookup = originalBeanName(name);
                if (args != null) {
                    // 委派父级容器根据指定名称和显式的参数查找
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    // 委派父容器根据指定名称和类型查找
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

            // 创建的 bean 是否需要进行类型验证,一般不需要
            if (!typeCheckOnly) {
                // 向容器标记指定的 bean 已经被创建
                markBeanAsCreated(beanName);
            }

            try {
                // 根据 beanName 获取对应的 RootBeanDefinition
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                // 获取当前 bean 所依赖bean 的 beanName,下面的 getBean(dependsOnBean) 方法会触发
                // getBean() 的递归调用,直到取到一个不依赖任何其它 bean 的 bean 为止。
                // 比如:beanA 依赖了 beanB,而 beanB 依赖了 beanC,那么在实例化 beanA 时会先实例化
                // beanC,然后实例化 beanB 并将 beanC 注入进去,最后实例化 beanA 时将 beanB 注入
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dependsOnBean : dependsOn) {
                        // 递归调用 getBean() 方法,从末级节点依次实例化 依赖的bean
                        getBean(dependsOnBean);
                        // 把 当前bean 直接依赖的bean 进行注册
                        //(也就是通过 setter 或构造方法将依赖的 bean 赋值给当前 bean 对应的属性)
                        registerDependentBean(dependsOnBean, beanName);
                    }
                }

                // 如果当前 bean 是单例的
                if (mbd.isSingleton()) {
                    // 这里使用了一个匿名内部类,创建 bean实例对象
                    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                        public Object getObject() throws BeansException {
                            try {
                                // 根据给定的 beanName 及 RootBeanDefinition对象,创建 bean 实例对象
                                return createBean(beanName, mbd, args);
                            }
                            catch (BeansException ex) {
                                destroySingleton(beanName);
                                throw ex;
                            }
                        }
                    });
                    // 获取给定 bean 的实例对象
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

                // 创建原型模式的 bean 实例对象
                else if (mbd.isPrototype()) {
                    // 原型模式 (Prototype) 每次都会创建一个新的对象
                    Object prototypeInstance = null;
                    try {
                        // 回调 beforePrototypeCreation() 方法,默认的功能是注册当前创建的原型对象
                        beforePrototypeCreation(beanName);
                        // 创建指定 bean 对象实例
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        // 回调 afterPrototypeCreation() 方法,默认的功能是告诉 IoC容器
                        // 指定 bean 的原型对象不再创建了
                        afterPrototypeCreation(beanName);
                    }
                    // 获取给定 bean 的实例对象
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }

                // 要创建的 bean 既不是单例模式,也不是原型模式,则根据该 bean元素 在配置文件中
                // 配置的生命周期范围,选择实例化 bean 的合适方法,这种在 Web 应用程序中
                // 比较常用,如:request、session、application 等的生命周期
                else {
                    // 获取此 bean 生命周期的范围
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    // bean 定义资源中没有配置生命周期范围,则该 bean 的配置不合法
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
                    }
                    try {
                        // 这里又使用了一个 ObjectFactory 的匿名内部类,获取一个指定生命周期范围的实例
                        Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                            public Object getObject() throws BeansException {
                                beforePrototypeCreation(beanName);
                                try {
                                    return createBean(beanName, mbd, args);
                                }
                                finally {
                                    afterPrototypeCreation(beanName);
                                }
                            }
                        });
                        // 获取给定 bean 的实例对象
                        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
        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(),根据之前解析生成的 BeanDefinition 对象 生成 bean 对象,下面我们看看 AbstractBeanFactory 的子类 AbstractAutowireCapableBeanFactory 中对 createBean() 的具体实现。

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {

    /**
     * 创建指定的 bean 实例对象
     */
    @Override
    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 {
            // 校验和准备 bean 中的方法覆盖
            mbd.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // 如果 bean 配置了后置处理器 PostProcessor,则这里返回一个 proxy 代理对象
            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;
    }

    /**
     * 创建 bean 实例对象的具体实现,Spring 中以 do 开头的都是方法的具体实现
     */
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {

        BeanWrapper instanceWrapper = null;
        // 如果这个 bean 是单例的,则从缓存中获取这个 beanName 对应的 BeanWrapper实例,并清除
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            /**
             * !!!!!!!!!!!!!
             * 创建实例对象
             * !!!!!!!!!!!!!
             */
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }

        // 获取实例化对象和其类型
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

        // 调用 PostProcessor 后置处理器
        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");
            }
            // 这里是一个 ObjectFactory 的匿名内部类,为了防止循环引用,尽早持有对象的引用
            addSingletonFactory(beanName, new ObjectFactory<Object>() {
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

        // bean 对象的初始化,依赖注入在此触发
        // 这个 exposedObject 在初始化完成之后,将返回作为依赖注入完成后的 bean
        Object exposedObject = bean;
        try {
            /**
             * !!!!!!!!!!!!!!!!!!!!!!!!!!!
             * 把生成的 bean对象 的依赖关系设置好,完成整个依赖注入过程
             * !!!!!!!!!!!!!!!!!!!!!!!!!!!
             */
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
                // 初始化 bean对象
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
            }
        }

        if (earlySingletonExposure) {
            // 获取指定名称的已注册的 单例bean对象
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                // 如果根据名称获取的已注册的 bean 和正在实例化的 bean 是同一个
                if (exposedObject == bean) {
                    // 当前实例化的 bean 初始化完成
                    exposedObject = earlySingletonReference;
                }
                // 如果当前 bean 依赖其他 bean,并且当发生循环引用时不允许新创建实例对象
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                    // 获取当前 bean 所依赖的其他 bean
                    for (String dependentBean : dependentBeans) {
                        // 对 依赖bean 进行类型检查
                        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.");
                    }
                }
            }
        }

        try {
            // 注册 成完依赖注入的bean
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        // 为应用返回所需要的实例对象
        return exposedObject;
    }
}

从源码中可以看到 createBeanInstance() 和 populateBean() 这两个方法与依赖注入的实现非常密切,createBeanInstance() 方法中生成了 bean 所包含的 Java 对象,populateBean() 方法对这些生成的 bean 对象之间的依赖关系进行了处理。下面我们先看一下 createBeanInstance() 方法的实现。

/**
 * 创建 bean 的实例对象
 */
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());
    }

    // 使用 RootBeanDefinition对象 中的 factoryMethodName 对 bean 进行实例化
    if (mbd.getFactoryMethodName() != null)  {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // 使用容器的自动装配方法进行实例化
    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) {
            // 配置了自动装配属性,使用容器的自动装配实例化,即,根据参数类型匹配 bean 的构造方法
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            // 使用默认的无参构造方法进行实例化
            return instantiateBean(beanName, mbd);
        }
    }

    // 使用 bean 的构造方法进行实例化
    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);
}

// 使用默认的无参构造方法实例化 bean对象
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        final BeanFactory parent = this;
        // 获取系统的安全管理接口,JDK 标准的安全管理 API
        if (System.getSecurityManager() != null) {
            // 这里使用了一个 PrivilegedAction 的匿名内部类,根据实例化策略创建实例对象
            beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    return getInstantiationStrategy().instantiate(mbd, beanName, parent);
                }
            }, getAccessControlContext());
        }
        else {
            /**
             * !!!!!!!!!!!!!!
             * 使用初始化策略实例化 bean 对象
             * !!!!!!!!!!!!!!
             */
            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);
    }
}

从源码中我们可以看到其调用了 SimpleInstantiationStrategy 实现类来生成 bean 对象,这个类是 Spring 用来生成 bean 对象 的默认类,它提供了两种策略来实例化 bean 对象,一种是利用 Java 的反射机制,另一种是直接使用 CGLIB。

public class SimpleInstantiationStrategy implements InstantiationStrategy {

    // 使用初始化策略实例化 bean对象
    public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
        // 如果 配置的bean 中没有方法覆盖,则使用 Java 的反射机制实例化对象,否则使用 CGLIB
        if (beanDefinition.getMethodOverrides().isEmpty()) {
            Constructor<?> constructorToUse;
            synchronized (beanDefinition.constructorArgumentLock) {
                // 获取对象的构造方法对 bean 进行实例化
                constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
                // 如果前面没有获取到构造方法,则通过反射获取
                if (constructorToUse == null) {
                    // 使用 JDK 的反射机制,判断要实例化的 bean 是否是接口
                    final Class clazz = beanDefinition.getBeanClass();
                    // 如果 clazz 是一个接口,直接抛出异常
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }
                    try {
                        if (System.getSecurityManager() != null) {
                            // 这里使用了一个 PrivilegedExceptionAction 的匿名内部类,使用反射机制获取 bean 的构造方法
                            constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {
                                public Constructor run() throws Exception {
                                    return clazz.getDeclaredConstructor((Class[]) null);
                                }
                            });
                        }
                        else {
                            constructorToUse =	clazz.getDeclaredConstructor((Class[]) null);
                        }
                        beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
                    }
                    catch (Exception ex) {
                        throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                    }
                }
            }
            // 根据传入的 Constructor,在 BeanUtils 中调用该 Constructor 的
            // newInstance(Object...) 方法,实例化指定对象
            return BeanUtils.instantiateClass(constructorToUse);
        }
        else {
            /**
             * !!!!!!!!!!!!!!
             * 使用 CGLIB 来实例化对象
             * 调用了 CglibSubclassingInstantiationStrategy 中的实现
             * !!!!!!!!!!!!!!
             */
            return instantiateWithMethodInjection(beanDefinition, beanName, owner);
        }
    }
}

在 SimpleInstantiationStrategy 的子类 CglibSubclassingInstantiationStrategy 中可以看到使用 CGLIB 进行实例化的源码实现。

public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {

    /**
     * 下面两个方法都通过实例化自己的私有静态内部类 CglibSubclassCreator,
     * 然后调用该内部类对象的实例化方法 instantiate() 完成实例化
     */
    protected Object instantiateWithMethodInjection(
            RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {

        return new CglibSubclassCreator(beanDefinition, owner).instantiate(null, null);
    }

    @Override
    protected Object instantiateWithMethodInjection(
            RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
            Constructor ctor, Object[] args) {

        return new CglibSubclassCreator(beanDefinition, owner).instantiate(ctor, args);
    }

    /**
     * 为避免 3.2 之前的 Spring 版本中的外部 cglib 依赖而创建的内部类。
     */
    private static class CglibSubclassCreator {

        private static final Log logger = LogFactory.getLog(CglibSubclassCreator.class);

        private final RootBeanDefinition beanDefinition;

        private final BeanFactory owner;

        public CglibSubclassCreator(RootBeanDefinition beanDefinition, BeanFactory owner) {
            this.beanDefinition = beanDefinition;
            this.owner = owner;
        }

        // 使用 CGLIB 进行 bean对象 实例化
        public Object instantiate(Constructor ctor, Object[] args) {
            // 实例化 Enhancer对象,并为 Enhancer对象 设置父类,生成 Java 对象的参数,比如:基类、回调方法等
            Enhancer enhancer = new Enhancer();
            // 将 bean 本身作为其父类
            enhancer.setSuperclass(this.beanDefinition.getBeanClass());
            enhancer.setCallbackFilter(new CallbackFilterImpl());
            enhancer.setCallbacks(new Callback[] {
                    NoOp.INSTANCE,
                    new LookupOverrideMethodInterceptor(),
                    new ReplaceOverrideMethodInterceptor()
            });

            // 使用 CGLIB 的 create() 方法生成实例对象
            return (ctor == null) ? enhancer.create() : enhancer.create(ctor.getParameterTypes(), args);
        }
    }
}

至此,完成了 bean 对象 的实例化,然后就可以根据解析得到的 BeanDefinition 对象 完成对各个属性的赋值处理,也就是依赖注入。这个实现方法就是前面 AbstractAutowireCapableBeanFactory 类中的 populateBean() 方法。

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {

    /**
     * 为属性赋值,完成依赖注入
     */
    protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        // 获取 RootBeanDefinition 中设置的 属性值PropertyValues,这些属性值来自对
        // .xml 文件中 bean元素 的解析
        PropertyValues pvs = mbd.getPropertyValues();

        // 如果 BeanWrapper对象 为 null,而要注入的属性值不为空,则抛出下述异常
        if (bw == null) {
            if (!pvs.isEmpty()) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
            else {
                // BeanWrapper对象 为 null,属性值也为空,不需要设置属性值,直接返回
                return;
            }
        }

        // 在设置属性之前调用 bean 的 PostProcessor 后置处理器
        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 名称自动装配注入
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }

            // 根据 bean 类型自动装配注入
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }

            pvs = newPvs;
        }

        // 检查容器是否持有用于处理单例模式 bean 关闭时的后置处理器
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        // bean实例对象 没有依赖,即没有继承基类
        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;
                        // 使用 BeanPostProcessor 处理器处理属性值
                        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) {
                // 设置安全上下文,JDK 安全机制
                ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
            }
        }

        if (pvs instanceof MutablePropertyValues) {
            mpvs = (MutablePropertyValues) pvs;
            // 如果属性值已经转换
            if (mpvs.isConverted()) {
                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;
        }
        // 创建一个 BeanDefinition 属性值解析器,将 BeanDefinition 中的属性值解析为 bean 实例对象的实际值
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

        // 为属性的解析值创建一个副本,最后将属性值注入到实例对象中
        List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
        boolean resolveNecessary = false;
        for (PropertyValue pv : original) {
            // 如果属性值已经转换,直接添加到 deepCopy 列表中
            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);
                }
                // 存储转换后的属性值,避免每次属性注入时的转换工作
                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 {
            /**
             * !!!!!!!!!!!!!!!!!!!!!
             * 完成 bean 的属性值注入的入口
             * 走 AbstractPropertyAccessor 中的实现方法
             * !!!!!!!!!!!!!!!!!!!!!
             */
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
        catch (BeansException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
        }
    }
}

BeanDefinitionValueResolver 中解析属性值,对注入类型进行转换的具体实现。

class BeanDefinitionValueResolver {

    /**
     * 解析属性值,对注入类型进行转换
     */
    public Object resolveValueIfNecessary(Object argName, Object value) {
        // 对引用类型的属性进行解析,RuntimeBeanReference 是在对 BeanDefinition 进行解析时生成的数据对象
        if (value instanceof RuntimeBeanReference) {
            RuntimeBeanReference ref = (RuntimeBeanReference) value;
            /**
             * !!!!!!!!!!!!!!!!
             * 解析引用类型的属性值
             * !!!!!!!!!!!!!!!!
             */
            return resolveReference(argName, ref);
        }

        // 对属性值是引用容器中另一个 bean 名称的解析
        else if (value instanceof RuntimeBeanNameReference) {
            String refName = ((RuntimeBeanNameReference) value).getBeanName();
            refName = String.valueOf(evaluate(refName));
            if (!this.beanFactory.containsBean(refName)) {
                throw new BeanDefinitionStoreException(
                        "Invalid bean name '" + refName + "' in bean reference for " + argName);
            }
            return refName;
        }
        // 对 BeanDefinitionHolder 类型属性的解析,主要是 bean 中的内部类
        else if (value instanceof BeanDefinitionHolder) {
            BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
            return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
        }
        else if (value instanceof BeanDefinition) {
            BeanDefinition bd = (BeanDefinition) value;
            return resolveInnerBean(argName, "(inner bean)", bd);
        }
        // 对集合数组类型的属性解析
        else if (value instanceof ManagedArray) {
            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) {
                        throw new BeanCreationException(
                                this.beanDefinition.getResourceDescription(), this.beanName,
                                "Error resolving array type for " + argName, ex);
                    }
                }
                // 没有获取到数组的类型,也没有获取到数组元素的类型
                // 则直接设置数组的类型为 Object
                else {
                    elementType = Object.class;
                }
            }
            // 创建指定类型的数组
            return resolveManagedArray(argName, (List<?>) value, elementType);
        }
        // 解析 list 类型的属性值
        else if (value instanceof ManagedList) {
            // May need to resolve contained runtime references.
            return resolveManagedList(argName, (List<?>) value);
        }
        // 解析 set 类型的属性值
        else if (value instanceof ManagedSet) {
            // May need to resolve contained runtime references.
            return resolveManagedSet(argName, (Set<?>) value);
        }
        // 解析 map 类型的属性值
        else if (value instanceof ManagedMap) {
            // May need to resolve contained runtime references.
            return resolveManagedMap(argName, (Map<?, ?>) value);
        }
        // 解析 Properties 类型的属性值,Properties 其实就是 key 和 value 均为字符串的 map
        else if (value instanceof ManagedProperties) {
            Properties original = (Properties) value;
            // 创建一个拷贝,用于作为解析后的返回值
            Properties copy = new Properties();
            for (Map.Entry 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;
        }
        // 解析字符串类型的属性值
        else if (value instanceof TypedStringValue) {
            TypedStringValue typedStringValue = (TypedStringValue) value;
            Object valueObject = evaluate(typedStringValue);
            try {
                // 获取属性的目标类型
                Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
                if (resolvedTargetType != null) {
                    // 对目标类型的属性进行解析,递归调用
                    return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
                }
                // 没有获取到属性的目标对象,则按 Object 类型返回
                else {
                    return valueObject;
                }
            }
            catch (Throwable ex) {
                throw new BeanCreationException(
                        this.beanDefinition.getResourceDescription(), this.beanName,
                        "Error converting typed String value for " + argName, ex);
            }
        }
        else {
            return evaluate(value);
        }
    }

    /**
     * 解析引用类型的属性值
     */
    private Object resolveReference(Object argName, RuntimeBeanReference ref) {
        try {
            // 获取 所引用bean 的 beanName
            String refName = ref.getBeanName();
            refName = String.valueOf(evaluate(refName));
            // 如果引用的对象在父容器中,则从父容器中获取指定的引用对象
            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);
            }
            // 从当前的容器中获取指定的引用 bean对象,如果指定的 bean 没有被实例化
            // 则会递归触发引用 bean 的初始化和依赖注入
            else {
                Object bean = this.beanFactory.getBean(refName);
                // 为 refName对应的bean 注入 它所依赖的bean
                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);
        }
    }

    /**
     * 解析 array 类型的属性
     */
    private Object resolveManagedArray(Object argName, List<?> ml, Class<?> elementType) {
        // 创建一个指定类型的数组,用于存放和返回解析后的数组
        Object resolved = Array.newInstance(elementType, ml.size());
        for (int i = 0; i < ml.size(); i++) {
            // 递归解析 array 的每一个元素,并将解析后的值设置到 resolved 数组中,索引为 i
            Array.set(resolved, i,
                    resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
        }
        return resolved;
    }

    /**
     * 解析 list 类型的属性
     */
    private List resolveManagedList(Object argName, List<?> ml) {
        List<Object> resolved = new ArrayList<Object>(ml.size());
        for (int i = 0; i < ml.size(); i++) {
            // 递归解析 list 的每一个元素
            resolved.add(
                    resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
        }
        return resolved;
    }

    /**
     * 解析 set 类型的属性
     */
    private Set resolveManagedSet(Object argName, Set<?> ms) {
        Set<Object> resolved = new LinkedHashSet<Object>(ms.size());
        int i = 0;
        // 递归解析 set 的每一个元素
        for (Object m : ms) {
            resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), m));
            i++;
        }
        return resolved;
    }

    /**
     * 解析 map 类型的属性
     */
    private Map resolveManagedMap(Object argName, Map<?, ?> mm) {
        Map<Object, Object> resolved = new LinkedHashMap<Object, Object>(mm.size());
        // 递归解析 map 中每一个元素的 key 和 value
        for (Map.Entry entry : mm.entrySet()) {
            Object resolvedKey = resolveValueIfNecessary(argName, entry.getKey());
            Object resolvedValue = resolveValueIfNecessary(
                    new KeyedArgName(argName, entry.getKey()), entry.getValue());
            resolved.put(resolvedKey, resolvedValue);
        }
        return resolved;
    }
}

至此,已经为依赖注入做好了准备,下面就该将 bean 对象 设置到它所依赖的另一个 bean 的属性中去。AbstractPropertyAccessor 和其子类 BeanWrapperImpl 完成了依赖注入的详细过程。先看一下 AbstractPropertyAccessor 中的实现。

public abstract class AbstractPropertyAccessor extends TypeConverterSupport implements ConfigurablePropertyAccessor {

    /**
     * setPropertyValues() 方法有多种重载,但最终都走的是
     * setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)重载方法
     */
    public void setPropertyValues(Map<?, ?> map) throws BeansException {
        setPropertyValues(new MutablePropertyValues(map));
    }

    public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown) throws BeansException {
        setPropertyValues(pvs, ignoreUnknown, false);
    }

    public void setPropertyValues(PropertyValues pvs) throws BeansException {
        setPropertyValues(pvs, false, false);
    }

    public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
            throws BeansException {

        List<PropertyAccessException> propertyAccessExceptions = null;
        List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
                ((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
        for (PropertyValue pv : propertyValues) {
            try {
                /**
                 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                 * 该方法走 BeanWrapperImpl 中的实现,这是 bean属性值注入 具体实现的入口
                 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                 */
                setPropertyValue(pv);
            }
            catch (NotWritablePropertyException ex) {
                if (!ignoreUnknown) {
                    throw ex;
                }
            }
            catch (NullValueInNestedPathException ex) {
                if (!ignoreInvalid) {
                    throw ex;
                }
            }
            catch (PropertyAccessException ex) {
                if (propertyAccessExceptions == null) {
                    propertyAccessExceptions = new LinkedList<PropertyAccessException>();
                }
                propertyAccessExceptions.add(ex);
            }
        }

        // 如果出现 PropertyAccessException 异常,则将这些异常积累起来放到一个集合中,然后一次性抛出!!!
        // 这种抛异常的方式 在实际的开发中也时常使用,可以好好看一下,对比一下
        if (propertyAccessExceptions != null) {
            PropertyAccessException[] paeArray =
                    propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]);
            throw new PropertyBatchUpdateException(paeArray);
        }
    }
}

最后看一下 BeanWrapperImpl 中的实现。

public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWrapper {

    @Override
    public void setPropertyValue(PropertyValue pv) throws BeansException {
        // PropertyTokenHolder 是一个用于内部使用的内部类
        PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
        if (tokens == null) {
            String propertyName = pv.getName();
            BeanWrapperImpl nestedBw;
            try {
                nestedBw = getBeanWrapperForPropertyPath(propertyName);
            }
            catch (NotReadablePropertyException ex) {
                throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
                        "Nested property in path '" + propertyName + "' does not exist", ex);
            }
            tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
            if (nestedBw == this) {
                pv.getOriginalPropertyValue().resolvedTokens = tokens;
            }

            /**
             * !!!!!!!!!!!!!!!
             * 进入 bean 属性值注入的具体实现
             * !!!!!!!!!!!!!!!
             */
            nestedBw.setPropertyValue(tokens, pv);
        }
        else {
            setPropertyValue(tokens, pv);
        }
    }

    /**
     * !!!!!!!!!!!!!!!!
     * 依赖注入(将某个bean所依赖的值 注入到这个bean中) 的具体实现
     * !!!!!!!!!!!!!!!!
     */
    @SuppressWarnings("unchecked")
    private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
        // PropertyTokenHolder 是定义在 BeanWrapperImpl 中的内部类,主要保存属性的名称、路径、
        // 以及集合的 size 等信息
        String propertyName = tokens.canonicalName;
        String actualName = tokens.actualName;

        // 对集合类型的属性注入,PropertyTokenHolder 的 keys 是用来保存集合类型属性的 size
        if (tokens.keys != null) {
            // 将属性信息从 tokens 拷贝到 getterTokens
            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 {
                // 通过反射机制,调用属性的 getter 方法获取属性值
                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);
            }
            // 获取集合类型属性的长度
            String key = tokens.keys[tokens.keys.length - 1];
            if (propValue == null) {
                if (this.autoGrowNestedPaths) {
                    int lastKeyIndex = tokens.canonicalName.lastIndexOf('[');
                    getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);
                    propValue = setDefaultValue(getterTokens);
                }
                else {
                    throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName,
                            "Cannot access indexed value in property referenced " +
                            "in indexed property path '" + propertyName + "': returned null");
                }
            }
            // 如果属性值是 Array 数组类型的,则注入 array 类型的属性值
            if (propValue.getClass().isArray()) {
                // 获取属性的描述符
                PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
                // 获取数组的类型
                Class requiredType = propValue.getClass().getComponentType();
                // 获取数组的长度
                int arrayIndex = Integer.parseInt(key);
                Object oldValue = null;
                try {
                    // 获取数组以前初始化的值
                    if (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {
                        oldValue = Array.get(propValue, arrayIndex);
                    }
                    // 将属性的值赋值给数组中的元素
                    Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
                            requiredType, TypeDescriptor.nested(property(pd), tokens.keys.length));
                    Array.set(propValue, arrayIndex, convertedValue);
                }
                catch (IndexOutOfBoundsException ex) {
                    throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
                            "Invalid array index in property path '" + propertyName + "'", ex);
                }
            }
            // 如果属性值是 List 类型的,则注入 list 类型的属性值
            else if (propValue instanceof List) {
                PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
                // 获取 list 集合中元素的类型
                Class requiredType = GenericCollectionTypeResolver.getCollectionReturnType(
                        pd.getReadMethod(), tokens.keys.length);
                List list = (List) propValue;

                int index = Integer.parseInt(key);
                Object oldValue = null;
                if (isExtractOldValueForEditor() && index < list.size()) {
                    oldValue = list.get(index);
                }
                // 获取 list 解析后的属性值
                Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
                        requiredType, TypeDescriptor.nested(property(pd), tokens.keys.length));
                // 获取 list 集合的 size
                int size = list.size();
                // 如果 list 的长度大于属性值的长度,则多余的元素赋值为 null
                if (index >= size && index < this.autoGrowCollectionLimit) {
                    for (int i = size; i < index; i++) {
                        try {
                            list.add(null);
                        }
                        catch (NullPointerException ex) {
                            throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
                                    "Cannot set element with index " + index + " in List of size " +
                                    size + ", accessed using property path '" + propertyName +
                                    "': List does not support filling up gaps with null elements");
                        }
                    }
                    list.add(convertedValue);
                }
                else {
                    try {
                        // 为 list 属性赋值
                        list.set(index, convertedValue);
                    }
                    catch (IndexOutOfBoundsException ex) {
                        throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
                                "Invalid list index in property path '" + propertyName + "'", ex);
                    }
                }
            }
            // 如果属性值是 Map 类型的,则注入 Map 类型的属性值
            else if (propValue instanceof Map) {
                PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
                // 获取 map 集合 key 的类型
                Class mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(
                        pd.getReadMethod(), tokens.keys.length);
                // 获取 map 集合 value 的类型
                Class mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(
                        pd.getReadMethod(), tokens.keys.length);
                Map map = (Map) propValue;
                TypeDescriptor typeDescriptor = (mapKeyType != null ?
                        TypeDescriptor.valueOf(mapKeyType) : TypeDescriptor.valueOf(Object.class));
                // 解析 map 类型属性 key 值
                Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType, typeDescriptor);
                Object oldValue = null;
                if (isExtractOldValueForEditor()) {
                    oldValue = map.get(convertedMapKey);
                }
                // 解析 map 类型属性 value 值
                Object convertedMapValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
                        mapValueType, TypeDescriptor.nested(property(pd), tokens.keys.length));
                // 将解析后的 key 和 value 值赋值给 map 集合属性
                map.put(convertedMapKey, convertedMapValue);
            }
            else {
                throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
                        "Property referenced in indexed property path '" + propertyName +
                        "' is neither an array nor a List nor a Map; returned value was [" + pv.getValue() + "]");
            }
        }
        // 对非集合类型的属性注入
        else {
            PropertyDescriptor pd = pv.resolvedDescriptor;
            if (pd == null || !pd.getWriteMethod().getDeclaringClass().isInstance(this.object)) {
                pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
                // 如果无法获取到属性名或者属性没有提供 setter 赋值方法
                if (pd == null || pd.getWriteMethod() == null) {
                    // 如果属性值是可选的,即不是必须的,则忽略该属性值
                    if (pv.isOptional()) {
                        logger.debug("Ignoring optional value for property '" + actualName +
                                "' - property not found on bean class [" + getRootClass().getName() + "]");
                        return;
                    }
                    // 如果属性值是必须的,则抛出无法给属性赋值,因为没提供 setter 方法的异常
                    else {
                        PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass());
                        throw new NotWritablePropertyException(
                                getRootClass(), this.nestedPath + propertyName,
                                matches.buildErrorMessage(), matches.getPossibleMatches());
                    }
                }
                pv.getOriginalPropertyValue().resolvedDescriptor = pd;
            }

            Object oldValue = null;
            try {
                Object originalValue = pv.getValue();
                Object valueToApply = originalValue;
                if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
                    if (pv.isConverted()) {
                        valueToApply = pv.getConvertedValue();
                    }
                    else {
                        if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
                            // 获取属性的 getter 方法
                            final Method readMethod = pd.getReadMethod();
                            // 如果属性的 getter 方法无法访问,则使用 Java 的反射机制强行访问 (暴力读取属性值)
                            if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) &&
                                    !readMethod.isAccessible()) {
                                if (System.getSecurityManager()!= null) {
                                    // 匿名内部类,根据权限修改属性的读取控制限制
                                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                                        public Object run() {
                                            readMethod.setAccessible(true);
                                            return null;
                                        }
                                    });
                                }
                                else {
                                    readMethod.setAccessible(true);
                                }
                            }
                            try {
                                 // 属性没有提供 getter 方法时,调用潜在的读取属性值的方法,获取属性值
                                if (System.getSecurityManager() != null) {
                                    oldValue = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                                        public Object run() throws Exception {
                                            return readMethod.invoke(object);
                                        }
                                    }, acc);
                                }
                                else {
                                    oldValue = readMethod.invoke(object);
                                }
                            }
                            catch (Exception ex) {
                                if (ex instanceof PrivilegedActionException) {
                                    ex = ((PrivilegedActionException) ex).getException();
                                }
                                if (logger.isDebugEnabled()) {
                                    logger.debug("Could not read previous value of property '" +
                                            this.nestedPath + propertyName + "'", ex);
                                }
                            }
                        }
                        // 设置属性的注入值
                        valueToApply = convertForProperty(propertyName, oldValue, originalValue, pd);
                    }
                    pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
                }
                // 根据 Java 的内省机制,获取属性的 setter方法
                final Method writeMethod = (pd instanceof GenericTypeAwarePropertyDescriptor ?
                        ((GenericTypeAwarePropertyDescriptor) pd).getWriteMethodForActualAccess() :
                        pd.getWriteMethod());
                // 如果属性的 setter方法 无法访问,则强行设置 setter方法 可访问 (暴力为属性赋值)
                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {
                    if (System.getSecurityManager()!= null) {
                        AccessController.doPrivileged(new PrivilegedAction<Object>() {
                            public Object run() {
                                writeMethod.setAccessible(true);
                                return null;
                            }
                        });
                    }
                    else {
                        writeMethod.setAccessible(true);
                    }
                }
                final Object value = valueToApply;
                 // 如果使用了 Java 的安全机制,则需要权限验证
                if (System.getSecurityManager() != null) {
                    try {
                        AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                            public Object run() throws Exception {
                                // 将属性值设置到属性上去
                                writeMethod.invoke(object, value);
                                return null;
                            }
                        }, acc);
                    }
                    catch (PrivilegedActionException ex) {
                        throw ex.getException();
                    }
                }
                else {
                    // 将属性值设置到属性上去
                    writeMethod.invoke(this.object, value);
                }
            }
            catch (TypeMismatchException ex) {
                throw ex;
            }
            catch (InvocationTargetException ex) {
                PropertyChangeEvent propertyChangeEvent =
                        new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
                if (ex.getTargetException() instanceof ClassCastException) {
                    throw new TypeMismatchException(propertyChangeEvent, pd.getPropertyType(), ex.getTargetException());
                }
                else {
                    throw new MethodInvocationException(propertyChangeEvent, ex.getTargetException());
                }
            }
            catch (Exception ex) {
                PropertyChangeEvent pce =
                        new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
                throw new MethodInvocationException(pce, ex);
            }
        }
    }
}

至此,完成了对 bean 的各种属性的依赖注入,在 bean 的实例化和依赖注入的过程中,需要依据 BeanDefinition 中的信息来递归地完成依赖注入。另外,在此过程中存在许多递归调用,一个递归是在上下文体系中查找 当前 bean 依赖的 bean 和创建 当前 bean 依赖的 bean 的递归调用;另一个是在依赖注入时,通过递归调用容器的 getBean() 方法,得到当前 bean 的依赖 bean,同时也触发对依赖 bean 的创建和注入;在对 bean 的属性进行依赖注入时,解析的过程也是递归的。这样,根据依赖关系,从最末层的依赖 bean 开始,一层一层地完成 bean 的创建和注入,直到最后完成当前 bean 的创建。

lazy-init 属性触发的依赖注入

最后看一下 lazy-init 触发的预实例化和依赖注入,发生在 IoC 容器完成对 BeanDefinition 的定位、载入、解析和注册之后。通过牺牲 IoC 容器初始化的性能,来有效提升应用第一次获取该 bean 的效率。
lazy-init 实现的入口方法在我们前面解读过的 AbstractApplicationContext 的 refresh() 中,它是 IoC 容器正式启动的标志。

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext, DisposableBean {

    /**
     * 容器初始化的过程:
     * 1、根据指定规则扫描指定目录,获取所有 用于配置bean的配置文件;
     * 2、根据 Spring定义的规则,解析配置文件中的各个元素,将其封装成 IoC容器 可以装载的 BeanDefinition对象;
     * 3、将封装好的 BeanDefinition 注册进 IoC容器。
     *
     * IoC容器的初始化 和 bean的依赖注入 是两个独立的过程,依赖注入一般发生在应用第一次通过 getBean()方法
     * 从容器获取 bean 时。
     * 另外需要注意的是,IoC容器 有一个预实例化的配置(即,将 <bean>元素 的 lazyInit属性 设为 false),
     * 使该 <bean>元素对应的 bean可以提前实例化,而不用等到调用 getBean()方法 时才开始实例化。
     */
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 调用容器准备刷新的方法,获取容器的当前时间,同时给容器设置同步标识
            prepareRefresh();

            // 告诉子类启动 refreshBeanFactory() 方法,BeanDefinition 资源文件的载入从子类的
            // refreshBeanFactory() 方法启动开始
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 为 BeanFactory 配置容器特性,例如类加载器、事件处理器等
            prepareBeanFactory(beanFactory);

            try {
                // 为容器的某些子类指定特殊的 BeanPost 事件处理器
                postProcessBeanFactory(beanFactory);

                // 调用所有注册的 BeanFactoryPostProcessor
                invokeBeanFactoryPostProcessors(beanFactory);

                // 为 BeanFactory 注册 BeanPost 事件处理器.
                // BeanPostProcessor 是 Bean 后置处理器,用于监听容器触发的事件
                registerBeanPostProcessors(beanFactory);

                // 初始化信息源,和国际化相关.
                initMessageSource();

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

                // 调用子类的某些特殊 Bean 初始化方法
                onRefresh();

                // 为事件传播器注册事件监听器.
                registerListeners();

                /**
                 * !!!!!!!!!!!!!!!!!!!!!
                 * 对配置了 lazy-init属性 为 false 的 bean 进行预实例化
                 * !!!!!!!!!!!!!!!!!!!!!
                 */
                finishBeanFactoryInitialization(beanFactory);

                // 初始化容器的生命周期事件处理器,并发布容器的生命周期事件
                finishRefresh();
            }

            catch (BeansException ex) {
                // 销毁以创建的单态 Bean
                destroyBeans();

                // 取消 refresh 操作,重置容器的同步标识.
                cancelRefresh(ex);

                throw ex;
            }
        }
    }

    /**
     * 对配置了 lazy-init属性 为 false 的 bean 进行预实例化
     */
    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 这是 Spring3 以后新加的代码,为容器指定一个转换服务 (ConversionService)
        // 在对某些 bean 属性进行转换时使用
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(
                    /**
                     * !!!!!!!!!!!!!!!!!!!!
                     * 在这里 通过调用 getBean()方法,触发依赖注入
                     * !!!!!!!!!!!!!!!!!!!!
                     */
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        // 为了类型匹配,停止使用临时的类加载器
        beanFactory.setTempClassLoader(null);

        // 缓存容器中所有注册的 BeanDefinition 元数据,以防被修改
        beanFactory.freezeConfiguration();

        // 对配置了 lazy-init属性 为 false 的 单例bean 进行预实例化处理
        beanFactory.preInstantiateSingletons();
    }
}

BeanPostProcessor接口

BeanPostProcessor 接口 也叫 Bean 后置处理器,作用是在 Bean 对象实例化和依赖注入完成后,在显示调用 bean 的 init-method(初始化方法)的前后添加我们自己的处理逻辑。注意是 Bean 实例化完毕后及依赖注入完成后触发的,接口的源码如下。

public interface BeanPostProcessor {
    /**
     * 实例化、依赖注入完毕,
     * 在调用显示的初始化之前完成一些定制的初始化任务
     */
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

    /**
     * 实例化、依赖注入、初始化完毕时执行
     */
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

使用方法也很简单,实现 BeanPostProcessor 接口,然后将实现类注入 IoC 容器即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值