Spring IOC

传统Java SE程序设计,直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象,现在是由容器来创建及注入依赖对象,依赖对象的获取被反转了。

ApplicationContext接口是BeanFactory的子接口,与BeanFactory一样,可以加载配置文件中定义的bean并进行管理。

Spring IOC_第1张图片

ApplicationContext接口主要的5个作用

Spring IOC_第2张图片

将配置文件中的bean信息解析成对应的BeanDefinition对象。


ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

Spring IOC_第3张图片xml文件解析使用BeanDefinitionReader实现类XmlBeanDefinitionReader。

BeanFactory是所有Bean容器的根接口,定义了spring容器基本方法。如使用 getBean(beanName,Class) 获取对象等。

Spring IOC_第4张图片

 

解析配置文件类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);
    // 告诉读取器 配置文件放在哪里,该方法继承于爷类 AbstractRefreshableConfigApplicationContext
    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 编程设计,我们在自己编码时也可以尝试这样设计自己的类图

/**
 * 在这里完成了容器的初始化,并赋值给自己私有的 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) 方法
 */
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(location, null);
}

/**
 * 获取在 IoC 容器初始化过程中设置的资源加载器
 */
public int loadBeanDefinitions(String location, Set 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 的读取和载入了。

将bean解析封装成BeanDefinition

Spring IoC 容器 BeanDefinition 解析过程就是把用户在配置文件中配置的 bean,解析并封装成 IoC 容器可以装载的 BeanDefinition 对象,BeanDefinition 是 Spring 定义的基本数据结构,其中的属性与配置文件中 bean 的属性相对应.

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 actualResources) 方法
 */
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(location, null);
}

/**
 * 获取在 IoC 容器初始化过程中设置的资源加载器
 */
public int loadBeanDefinitions(String location, Set 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 currentResources = this.resourcesCurrentlyBeingLoaded.get();
    if (currentResources == null) {
        currentResources = new HashSet(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) {
    // 解析  元素
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
        importBeanDefinitionResource(ele);
    }
    // 解析  元素
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
        processAliasRegistration(ele);
    }
    // 若元素节点既不是  也不是 ,即普通的  元素,
    // 则按照 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);
    }
}

/**
 * 解析  元素
 */
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 actualResources = new LinkedHashSet(4);

    // 标识给定的  元素的 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 {
        // 给定的  元素的 location 是相对路径
        try {
            int importCount;
            // 将给定  元素的 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()]);
    // 在解析完  元素之后,发送容器导入其他资源处理完成事件
    getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
}

/**
 * 解析  元素
 */
protected void processAliasRegistration(Element ele) {
    // 获取  元素中的 name 属性值
    String name = ele.getAttribute(NAME_ATTRIBUTE);
    // 获取  元素中的 alias 属性值
    String alias = ele.getAttribute(ALIAS_ATTRIBUTE);
    boolean valid = true;
    // 若  元素的 name 属性值为空
    if (!StringUtils.hasText(name)) {
        getReaderContext().error("Name must not be empty", ele);
        valid = false;
    }
    // 若  元素的 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);
        }
        // 在解析完  元素之后,向容器发送别名处理完成事件
        getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));
    }
}

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

    // BeanDefinitionHolder 是对 BeanDefinition 的进一步封装,持有一个 BeanDefinition 对象 及其对应
    // 的 beanName、aliases别名。对  元素的解析由 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 元素的详细解析过程。

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

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

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

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

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

    String beanName = id;
    // 如果  元素中没有配置 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");
        }
    }

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

    // 将  元素解析成 BeanDefinition对象
    AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
    if (beanDefinition != null) {
        if (!StringUtils.hasText(beanName)) {
            try {
                // 如果  元素中没有配置 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 的 id、name 及 alias 属性进行了处理
 */
public AbstractBeanDefinition parseBeanDefinitionElement(
        Element ele, String beanName, BeanDefinition containingBean) {

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

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

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

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

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

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

        // 解析  元素的构造方法
        parseConstructorArgElements(ele, bd);
        // 解析  元素中的所有  元素
        parsePropertyElements(ele, bd);
        // 解析  元素的 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();
    }
    // 解析  元素出错时,返回 null
    return null;
}

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

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

/**
 * 详细解析  元素
 */
public void parsePropertyElement(Element ele, BeanDefinition bd) {
    // 获取  元素的名字
    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);
        // 解析  元素
        parseMetaElements(ele, pv);
        pv.setSource(extractSource(ele));
        // 为当前的 BeanDefinition对象设置 propertyValues 属性值
        bd.getPropertyValues().addPropertyValue(pv);
    }
    finally {
        this.parseState.pop();
    }
}

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

    // 获取  的所有子元素,只能是其中一种类型: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 {// 当前  元素包含有子元素
                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;
    }
    // 如果当前  元素还有子元素
    else if (subElement != null) {
        // 解析  的子元素
        return parsePropertySubElement(subElement, bd);
    }
    else {
        // propery 属性中既不是 ref,也不是 value 属性,解析出错返回 null
        error(elementName + " must specify a ref or value", ele);
        return null;
    }
}

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

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

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

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

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

/**
 * 具体解析  集合元素, 都使用该方法解析
 */
protected void parseCollectionElements(NodeList elementNodes, Collection 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 容器中。

将BeanDefinition注册进IoC容器

将前面解析出来的 BeanDefinition 对象 注册进 IoC 容器,其实就是存入一个 ConcurrentHashMap 中。

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

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

    // BeanDefinitionHolder 是对 BeanDefinition 的进一步封装,它持有一个 BeanDefinition 对象 及其对应
    // 的 beanName、aliases别名。
    // 对 Document 对象中  元素的解析由 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 {

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

    // 如果解析的 元素 有别名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 beanDefinitionNames = new ArrayList();

    /** IoC容器 的实际体现,key --> beanName,value --> BeanDefinition对象 */
    private final Map beanDefinitionMap = new ConcurrentHashMap(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);
    }
}

依赖注入(DI)

前面我们主要分析了 FileSystemXmlApplicationContext 这个具体的 IoC 容器实现类 的初始化源码,在 IoC 容器 中建立了 beanName 到 BeanDefinition 的数据映射,通过一个 ConcurrentHashMap。

Spring 是如何将 IoC 容器中存在依赖关系的 bean 根据配置联系在一起的。Spring 中触发 IoC 容器“依赖注入” 的方式有两种,一个是应用程序通过 getBean()方法 向容器索要 bean 实例 时触发依赖注入;另一个是提前给 bean 配置了 lazy-init 属性为 false,Spring 在 IoC 容器 初始化会自动调用此 bean 的 getBean() 方法,提前完成依赖注入。总的来说,想提高运行时获取 bean 的效率,可以考虑配置此属性。

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

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

    //---------------------------------------------------------------------
    // BeanFactory 接口的实现,下列的 getBean() 方法不论是哪种重载,最后都会走
    // doGetBean(final String name, final Class 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 getBean(String name, Class 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 getBean(String name, Class requiredType, Object... args) throws BeansException {
        return doGetBean(name, requiredType, args, false);
    }

    // 真正实现向 IoC容器 获取 bean 的功能,也是触发 依赖注入(DI) 的地方
    @SuppressWarnings("unchecked")
    protected  T doGetBean(final String name, final Class 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() {
                        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() {
                            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() {
                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 actualDependentBeans = new LinkedHashSet(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() {
                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() {
                                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 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 deepCopy = new ArrayList(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 resolved = new ArrayList(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 resolved = new LinkedHashSet(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 resolved = new LinkedHashMap(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 propertyAccessExceptions = null;
        List 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();
                }
                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() {
                                        public Object run() {
                                            readMethod.setAccessible(true);
                                            return null;
                                        }
                                    });
                                }
                                else {
                                    readMethod.setAccessible(true);
                                }
                            }
                            try {
                                 // 属性没有提供 getter 方法时,调用潜在的读取属性值的方法,获取属性值
                                if (System.getSecurityManager() != null) {
                                    oldValue = AccessController.doPrivileged(new PrivilegedExceptionAction() {
                                        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() {
                            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() {
                            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容器 有一个预实例化的配置(即,将 元素 的 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
                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 容器即可。

你可能感兴趣的:(开源框架,spring,java,后端)