IoC容器系列的设计与实现:BeanFactory和ApplicationContext

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 2 Spring IoC容器的设计下图描述了IoC容器中的主要接口设计这里写图片描述简要分析:从BeanFactory到HierarchicalbeanFactory再到ConfigurableBeanFactory是一条主要的BeanFactory设计路径.

2 Spring IoC容器的设计

下图描述了IoC容器中的主要接口设计


img_0156e4b6f4c40ce6aac5c8cac63ffc63.png
这里写图片描述

简要分析:

  • BeanFactoryHierarchicalbeanFactory再到ConfigurableBeanFactory是一条主要的BeanFactory设计路径.BeanFactory定义了基本的IoC容器的规范,包括getBean()这样的IoC容器的基本方法.HierarchicalBeanFactory继承了BeanFactory,增加了getParentBeanFactory()功能,使得BeanFactory具备双亲IoC容器的管理功能.ConfigurableBeanFactory主要定义了对BeanFactory的配置功能. 通过这些接口的设计,定义了BeanFactory就是简单IoC容器的基本功能.
  • ApplicationContext为核心的接口设计.

2.1 BeanFactory的应用场景

2.2 BeanFactory容器的设计原理

img_b3b6463d50bb0ed6fa725672bb11acb7.png
这里写图片描述

我们从最基本的XmlBeanFactory看起,它是简单IoC容器系列的最底层实现,与我们在Spring的那些上下文相比,它只提供了最基本的IoC容器的功能.
我们可以认为直接的BeanFactory实现是IoC容器的基本形式,而各种ApplicationContext的实现是IoC容器的高级表现形式.

继承自DefaultListableBeanFactory类,DefaultListableBeanFactory实际上已经包含了基本IoC容器所具有的重要功能.在Spring中实际上是把DefaultListableBeanFactory作为一个默认的功能完整的IoC容器来使用的.而XmlBeanFactory继承了它之后,又增加了新的功能:它是一个可以读取以XML文件定义BeanDefinition的IoC容器

在Spring 4中,该类已经不推荐被使用了

package org.springframework.beans.factory.xml;
@Deprecated
@SuppressWarnings({"serial", "all"})
public class XmlBeanFactory extends DefaultListableBeanFactory {

    private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);

    /**
     * 通过给定的资源创建一个XmlBeanFactory实例。
     */
    public XmlBeanFactory(Resource resource) throws BeansException {
        this(resource, null);
    }
    
    /**
     * Create a new XmlBeanFactory with the given input stream,
     * which must be parsable using DOM.
     */
    public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
        super(parentBeanFactory);
        this.reader.loadBeanDefinitions(resource);
    }
}

XmlBeanFactory又是怎样实现读取XML文件的呢?

  1. 其实,对这些xml文件的处理并不是由XmlBeanFactory直接完成的,而是它里面初始化的一个XmlBeanDefinitionReader对象.
  2. 在构建XmlBeanFactory这个IoC容器时,需要指定BeanDefinition的信息来源,而且这个来源需要封装成Spring中的Resource类来给出.(Resource是Spring用来封装I/O操作的类).
  3. 将前面构造的Resource作为构造参数传递给XmlBeanFactory构造函数.这样IoC容器就可以定位到这个BeanDefinition,从而对Bean完成容器的初始化和依赖注入过程

如下是一个简单的编程式使用IoC容器的例子

// 创建IoC配置文件的抽象资源(包含BeanDefinition的定义信息)
ClassPathResource res = new ClassPathResource("bean.xml");
// 创建一个BeanFactory
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 创建一个载入BeanDefinition的读取器
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
// 从定义好的资源位置读入配置信息
reader.loadBeanDefinitions(res);

3 ApplicationContext的应用场景

上一节中我们了解了IoC容器建立的基本步骤,可以很方便的通过编程的方式来手动控制这些配置和容器的建立过程.但在Spring中为我们提供了许多已经定义好的容器实现,如ApplicationContext.
如图可以看到ApplicationContext在BeanFactory基础上添加的附加功能.

img_a729fa6375a15658d2b89bf702c55df2.png
这里写图片描述

  1. 支持不同的信息源
    通过扩展了MessageSource接口,信息源的扩展功能可以支持国际化实现,为开发多语言版本提供支持
  2. 访问资源
    体现在对ResourceLoaderResource的支持上,这样我们可以从不同地方得到Bean定义的资源,尤其是从不同的I/O途径.
  3. 支持应用事件
    继承了接口ApplicationEventPublisher,从而在上下文中引入事件机制.和Bean的生命周期结合为Bean的管理提供了便利.

4 ApplicationContext容器的设计原理

以常用的FileSytemXmlApplicationContext实现为例来说明ApplicationContext容器设计原理.

在其设计中,可以看到ApplicationContext的主要功能已经在它的基类AbstractXmlApplicationContext中实现了.在FileSystemXmlApplicationContext中,只需要实现和它自身设计相关的两个功能:

  • 功能一:如果应用直接使用FileSystemXmlApplicationContext,对于实例化这个应用上下文的支持,同时启动IoC容器的refresh()过程.
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {            
        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }

这个refresh()过程会牵涉IoC容器启动的一系列复杂操作,对于不同的容器实现,这些操作都是类似的,所以在基类中将它们封装好.所以我们在FileSystemXml的设计中看到的只是一个简单的调用.

  • 功能二:与FileSystemXmlApplicationContext设计具体相关的功能,这部分与怎样从文件系统中加载XML的Bean定义资源有关
    通过此过程,可以为在文件系统中读取以XML形式存在的BeanDefinition做准备,因为不同的应用上下文对应着不同的读取BeanDefinition的方式,在其中实现的代码如下
@Override
protected Resource getResourceByPath(String path) {
    if (path != null && path.startsWith("/")) {
        path = path.substring(1);
    }
    return new FileSystemResource(path);
}

调用这个方法,可得到FileSystemResource的资源定位

可以发现,在FileSystemXmlApplicationContext中不管调用哪个构造函数,最终都会调用这个包含 refresh() 方法的构造函数,因此可得出结论:
触发对BeanDefinition资源定位过程的refresh()方法的调用是在FileSystemXmlApplicationContext的构造函数中启动的

目录
相关文章
|
4月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
2月前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
79 0
|
3月前
|
XML Java 开发者
经典面试---spring IOC容器的核心实现原理
作为一名拥有十年研发经验的工程师,对Spring框架尤其是其IOC(Inversion of Control,控制反转)容器的核心实现原理有着深入的理解。
151 3
|
4月前
|
XML Java 数据格式
Spring5入门到实战------5、IOC容器-Bean管理(三)
这篇文章深入探讨了Spring5框架中IOC容器的高级Bean管理,包括FactoryBean的使用、Bean作用域的设置、Bean生命周期的详细解释以及Bean后置处理器的实现和应用。
Spring5入门到实战------5、IOC容器-Bean管理(三)
|
4月前
|
XML Java 数据格式
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
这篇文章是Spring5框架的入门教程,详细讲解了IOC容器中Bean的自动装配机制,包括手动装配、`byName`和`byType`两种自动装配方式,并通过XML配置文件和Java代码示例展示了如何在Spring中实现自动装配。
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
|
4月前
|
XML Java 数据格式
Spring5入门到实战------2、IOC容器底层原理
这篇文章深入探讨了Spring5框架中的IOC容器,包括IOC的概念、底层原理、以及BeanFactory接口和ApplicationContext接口的介绍。文章通过图解和实例代码,解释了IOC如何通过工厂模式和反射机制实现对象的创建和管理,以及如何降低代码耦合度,提高开发效率。
Spring5入门到实战------2、IOC容器底层原理
|
4月前
|
XML Java 数据格式
Spring5入门到实战------8、IOC容器-Bean管理注解方式
这篇文章详细介绍了Spring5框架中使用注解进行Bean管理的方法,包括创建Bean的注解、自动装配和属性注入的注解,以及如何用配置类替代XML配置文件实现完全注解开发。
Spring5入门到实战------8、IOC容器-Bean管理注解方式
|
11天前
|
监控 NoSQL 时序数据库
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
142 77
|
20天前
|
监控 Docker 容器
在Docker容器中运行打包好的应用程序
在Docker容器中运行打包好的应用程序
|
4天前
|
关系型数据库 应用服务中间件 PHP
实战~如何组织一个多容器项目docker-compose
本文介绍了如何使用Docker搭建Nginx、PHP和MySQL的环境。首先启动Nginx容器并查看IP地址,接着启动Alpine容器并安装curl测试连通性。通过`--link`方式或`docker-compose`配置文件实现服务间的通信。最后展示了Nginx配置文件和PHP代码示例,验证了各服务的正常运行。
20 3
实战~如何组织一个多容器项目docker-compose
下一篇
DataWorks