Spring-IOC容器接口设计与功能

简介: 上一篇文章中我们说到了Spring IOC提供了一个基本的JavaBean容器,通过IOC容器把获取资源的方式反转,Spring使用IOC容器管理依赖关系,将依赖注入到组件中,使依赖的管理和配置更加灵活。那么在Spring中,IOC容器具体是如何设计和实现的呢?在Spring中,IOC容器是如何体现的呢?下面我们一起学习下。

上一篇文章中我们说到了Spring IOC提供了一个基本的JavaBean容器,通过IOC容器把获取资源的方式反转,Spring使用IOC容器管理依赖关系,将依赖注入到组件中,使依赖的管理和配置更加灵活。那么在Spring中,IOC容器具体是如何设计和实现的呢?在Spring中,IOC容器是如何体现的呢?下面我们一起学习下。


IOC容器接口设计:

在SpringIOC容器设计中,有两个主要的容器系列,一个是实现BeanFactory接口的简单容器系列,这系列容器只实现了容器的最基本功能;另一个是ApplicationContext应用上下文,它作为容器的高级形态而存在。ApplicationContext应用上下文在BeanFactory的基础上,增加了很多面向框架的特性,同时对应用环境作了许多适配。


f343b5990a0fd0b2f4c1c4330d04de1e.png


注意,这张图是ioc容器的接口设计图,我们知道接口主要用于功能的扩展,从图中我们可以看出IOC容器的设计都包含了哪些功能。


主要有两条设计主线,分别是一条以BeanFactory为主和一条以ApplicationContext为主的设计主线。ApplicationContext是在BeanFactory添加了许多特性的高级容器。


BeanFactory设计主线:从BeanFactory到HierarchicalBeanFactory再到ConfigurableBeanFactory。BeanFactory定义了基本的IOC容器的规范,包括了getBean()这样的IOC容器基本方法;继承HierarchicalBeanFactory接口,添加了getParentBeanFactory()方法,从而使BeanFactory具备了双亲IOC容器的管理功能;继承ConfigurableBeanFactory接口,主要定义了一些对BeanFactory的配置功能,比如通过setParentBeanFactory()设置双亲IOC容器,通过addBeanPostProcessor()配置Bean后置处理器等。通过这样接口设计的叠加,定义了简单IOC容器的基本功能。


ApplicationContext设计主线:从BeanFactory到ListableBeanFactory再到ApplicationContet,再到我们常用的WebApplicationContext或者ConfigurableApplicationContext接口。继承ListableBeanFactory,细化了许多BeanFactory的接口功能。同时ApplicationContext通过继承MessageSource,ResourceLoader,ApplicationEventPublisher接口,在BeanFactory简单的IOC容器基础上添加了许多高级容器的特性的支持。


当我们想实现一个具体容器时,通过实现相应的接口来完成。比如DefaultListableBeanFactory是实现了ConfigurableBeanFactory,从而成为一个简单IOC容器。


下面是我们看下两个重要的容器:BeanFactory和ApplicationContext.

BeanFactory


BeanFactory是最基本的IOC容器,提供了IOC容器的基本功能,如:getBean(String name)方法,根据名称获取Bean;containsBean(String name)让用户判断是否有包含此名称的Bean等。如接口方法所示:

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";
    Object getBean(String name) throws BeansException; 
    <T > T getBean(String name, Class < T > requiredType) throws BeansException;
    Object getBean(String name, Object...args) throws BeansException; 
    <T > T getBean(Class < T > requiredType) throws BeansException; 
    <T > T getBean(Class < T > requiredType, Object...args) throws BeansException;
    boolean containsBean(String name);
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
    boolean isTypeMatch(String name, Class << ? > typeToMatch) throws NoSuchBeanDefinitionException;
    Class << ? > getType(String name) throws NoSuchBeanDefinitionException;
    String[] getAliases(String name);
}



Spring除了提供了一系列访问Bean的接口。我们前面说过,还提供了对该接口的一系列实现供开发者直接使用,以xmlBeanFactory为例:


54b1a4151b8c4aa173908f44cf840183.png


从图中的继承关系,我们可以看出xmlBeanFactory通过层层继承,实现了BeanFactory的接口功能。在XmlBeanFactory中,通过Resource封装BeanDefinition的来源,然后将Resource通过构造函数传递给xmlBeanFactory,再通过XmlBeanDefinitionReader解析BeanDefinition,从定义好的资源位置读入配置信息,完成Bean的载入和注册。


因为一些原因,Spring 3.1以后已经废弃了XmlBeanFactory这个类了,现在推荐使用的是ApplicationContext。我的版本是4.3.1,所以上图中XmlBeanFactory上有横线,表示已废弃。


https://blog.csdn.net/xlecho/article/details/115828549


ApplicationContext


ApplicationContext是IOC容器的高级实现,有很多高级特性,在BeanFactory基础上添加了附加功能,如:支持不同的信息源,访问资源,支持应用事件,在ApplicationContext中提供的附加服务。


以FileSystemXmlApplicationContext为例,ApplicationContext的主要功能,已经在FileSystemXmlApplicationContext 的基类AbstractXmlApplicationContext中实现了。FileSystemXmlApplicationContext 只需要再实现自身设计的功能。


b7a3c705cba409e85f82ecf2ff93ecec.png



主要功能有两个:

  1. 如果应用直接使用FileSystemXmlApplicationContext 实例化上下文的同时,启动IOC容器的refresh()过程。代码如下:
1. public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
            throws BeansException {
        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }



  1. 与FileSystemXmlApplicationContext具体设计相关的功能:从文件系统中加载xml的BeanDefiniton资源。代码如下:
@Override
    protected Resource getResourceByPath(String path) {
        if (path != null && path.startsWith("/")) {
            path = path.substring(1);
        }
        return new FileSystemResource(path);
    }


总结:



通过这两个容器分析我们可以看出,Spring中,BeanFactory定义了容器功能的基本规范,如获取Bean,判断Bean的类型等。同时,Spring在BeanFactory基础上进行了层层扩展,使容器的功能更加丰富,如ApplicationContext继承ResourceLoader接口,使容器可以从不同地方获取BeanDefinition资源,使用户程序可以灵活的定义BeanDefinition信息;继承MessageSource接口,使容器支持参数化和国际化等。所以我们也更清楚的理解了为什么说ApplicationContext是IOC容器的高级实现,简单来说就是ApplicationContext,在BeanFactory的基础上扩展了更多高级的功能。与BeanFactory相比,对ApplicationContext的使用是一种面向框架的使用风格,所以一般建议在开发应用时,使用ApplicationContext作为IOC容器的基本形式。


同时,Spring也为开发者提供了提供了很多IOC容器的实现,开发者可以直接拿过来用。如从文件系统中加载xml形式的BeanDefinition生成IOC容器的FileSystemXmlApplicationContext。读取注解形式的BeanDefinition生成IOC容器的AnnotationConfigApplicationContext等。


大家在阅读源码时,可以先看一下类图,通过类图中的继承关系,我们能大概猜到此容器的主要功能。


通过上面的阅读,相信读者对IOC容器的设计和功能已经有了一个基本的认识。那么IOC容器是如何初始化的呢?如何读取不同形式的BeanDefiniton,生成Bean注册到容器中的呢?请看下一篇:Spring-IOC容器初始化过程


相关文章
|
8天前
|
消息中间件 缓存 Java
手写模拟Spring Boot启动过程功能
【11月更文挑战第19天】Spring Boot自推出以来,因其简化了Spring应用的初始搭建和开发过程,迅速成为Java企业级应用开发的首选框架之一。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,帮助读者深入理解其工作机制。
22 3
|
8天前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
28 0
|
1月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
42 4
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
151 1
|
1月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
37 0
|
21天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
96 62
|
7天前
|
Ubuntu 网络安全 容器
KubeSphere 是一个开源的容器平台,提供丰富的功能和便捷的操作界面,适用于企业容器化部署和管理
KubeSphere 是一个开源的容器平台,提供丰富的功能和便捷的操作界面,适用于企业容器化部署和管理。本文详细介绍了如何在 Ubuntu 22.04 上安装 KubeSphere,包括系统要求、安装依赖项、设置防火墙、下载安装脚本、选择安装选项、验证安装结果等步骤,并提供了常见问题的解决方法。希望本文能为读者提供实用的参考和帮助。
19 3
|
19天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
37 2
|
1月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第8天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建并配置 Spring Boot 项目,实现后端 API 和安全配置。接着,使用 Ant Design Pro Vue 脚手架创建前端项目,配置动态路由和菜单,并创建相应的页面组件。最后,通过具体实践心得,分享了版本兼容性、安全性、性能调优等注意事项,帮助读者快速搭建高效且易维护的应用框架。
41 3