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容器初始化过程


相关文章
|
5天前
|
XML Java 数据库连接
Spring6(二):IoC容器(2)
Spring6(二):IoC容器
13 2
|
5天前
|
XML Java 数据格式
Spring6(二):IoC容器(3)
Spring6(二):IoC容器(3)
10 1
|
5天前
|
XML Java 数据格式
Spring6(二):IoC容器(1)
Spring6(二):IoC容器(1)
13 1
|
7天前
|
Java Spring 容器
使用ContextLoaderListener初始化Spring容器
使用ContextLoaderListener初始化Spring容器
|
5天前
|
开发框架 Java 开发者
Spring框架的最新功能与应用案例解析
Spring框架的最新功能与应用案例解析
|
13天前
|
存储 Java 分布式数据库
Spring Boot 优雅实现hbase功能
【6月更文挑战第24天】要在 Spring Boot 项目中实现 HBase 和 Memcached 的功能,首先需要理解各自的原理和作用,然后通过实际操作将其集成到 Spring Boot 项目中。
33 6
|
11天前
|
XML Java 数据格式
经验大分享:Spring基础篇——Spring容器和应用上下文理解
经验大分享:Spring基础篇——Spring容器和应用上下文理解
12 1
|
17天前
|
安全 Java Maven
在 Spring Boot 中实现邮件发送功能可以通过集成 Spring Boot 提供的邮件发送支持来完成
在 Spring Boot 中实现邮件发送功能可以通过集成 Spring Boot 提供的邮件发送支持来完成
22 2
|
17天前
|
缓存 监控 安全
在 Spring Boot 中使用 AOP(Aspect-Oriented Programming)实现日志记录功能
在 Spring Boot 中使用 AOP(Aspect-Oriented Programming)实现日志记录功能
22 1
|
17天前
|
监控 NoSQL Java
在 Spring Boot 中实现 Redis 的发布/订阅功能可以通过 RedisTemplate 和消息监听器来完成
在 Spring Boot 中实现 Redis 的发布/订阅功能可以通过 RedisTemplate 和消息监听器来完成
16 1