Spring框架 -- BeanFactory 和 ApplicationContext之间的区别

前言

Spring 通过一个配置文件描述 Bean 及 Bean 之间的依赖关系,利用 Java 语言的反射功能实例化 Bean 并建立 Bean 之间的依赖关系。

Spring 的 IoC 容器在完成这些底层工作的基础上,还提供了 Bean 实例缓存、生命周期管理、Bean 实例代理、事件发布、资源装载等高级服务。

Bean 工厂(com.springframework.beans.factory.BeanFactory)是 Spring 框架最核心的口,它提供了高级 IoC 的配置机制。BeanFactory 使管理不同类型的 Java 对象成为可能,

ApplicationContext应用上下文(com.springframework.context.)建立在 BeanFactory 基础之上,提供了更多面向应用的功能,它提供了国际化支持和框架事件体系,更易于创建实际应用。我们一般称BeanFactory 为 IoC 容器,而称 ApplicationContext 为应用上下文。但有时为了行文方便,我们也ApplicationContext 称为 Spring 容器。

对于两者的用途,我们可以进行简单划分:

  • BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;
  • ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的应用场合我们都直接使用ApplicationContext 而非底层的 BeanFacto

ApplicationContext 类体系结构
在这里插入图片描述

BeanFactory 的类体系结构
在这里插入图片描述

首先对于BeanFactory 进行简单介绍

定义

BeanFactory 是一个类的通用工厂,它可以创建并管理各种类的对象。这些可被创建和管理的对象实例,,Spring 把这些称为 Bean。

解释

BeanFactory 接口位于类结构树的顶端,主要的方法就是 getBean(String beanName),该方法从容器中返回特定名称的 Bean,BeanFactory 的功能通过其他的接口得到不断扩展

查看接口

  • ListableBeanFactory:该接口定义了访问容器中 Bean 基本信息的若干方法,如查看Bean 的个数、获取某一类型 Bean 的配置名、查看容器中是否包括某一 Bean 等方法;
  • HierarchicalBeanFactory:父子级联 IoC 容器的接口,子容器可以通过接口方法访问父容器;
  • ConfigurableBeanFactory:是一个重要的接口,增强了 IoC 容器的可定制性,它定义了设置类装载器、属性编辑器、容器初始化后置处理器等方法
  • AutowireCapableBeanFactory:定义了将容器中的 Bean 按某种规则(如按名字匹配、
    按类型匹配等)进行自动装配的方法;
  • SingletonBeanRegistry:定义了允许在运行期间向容器注册单实例 Bean 的方法;
  • BeanDefinitionRegistry:Spring 配置文件中每一个节点元素在 Spring 容器里
    都通过一个 BeanDefinition 对象表示,它描述了 Bean 的配置信息。而 BeanDefinition
    Registry 接口提供了向容器手工注册 BeanDefinition 对象的方法。

举例:

在xml中配置一个Bean
在这里插入图片描述
通过 XmlBeanFactory 实现类启动 Spring IoC 容器的bean:
在这里插入图片描述
解释

创建支持ant风格的资源加载的实现类,调用getResource加载资源,创建xmlBeanFactory生成器,生成资源获得BeanFactory接口,调用实例化getBean返回实例Car

XmlBeanFactory 是通过 Resource 装载 Spring 配置信息并启动 IoC 容器,然后就可以通过 BeanFactory方法getBean(beanName)方法从 IoC 容器中获取 Bean 了。通过 BeanFactory 启动IoC 容器时,并不会初始化配置文件中定义的 Bean,初始化动作发生在第一个调用时。对于单实例(singleton)的 Bean 来说,BeanFactory会缓存 Bean 实例,所以第二次使用 getBean()获取 Bean 时将直接从 IoC 容器的缓存中获取 Bean 实例。

ApplicationContext 简单介绍

定义:

ApplicationContext 由 BeanFactory 派生而来,对此提供了更多面向实际应用的功能。在BeanFactory 中,很多功能需要以编程的方式实现,而在 ApplicationContext 中则可以通过配置的方式实现
在这里插入图片描述
从图上结构我们可以看出 ApplicationContext 继承了 HierarchicalBeanFactory 和
ListableBeanFactory 接口,在此基础上,还通过多个其他的接口扩展了 BeanFactory 的功能,

这些接口包括:

  • ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能,包括容器启动事件、关闭事件等。实现了 ApplicationListener 事件监听接口的 Bean 可以接收到容器事件,并对事件进行响应处理。在 ApplicationContext 抽象实现类
    AbstractApplicationContext 中,我们可以发现存在一个 ApplicationEventMulticaster,
    它负责保存所有监听器,以便在容器产生上下文事件时通知这些事件监听者。
  • MessageSource:为应用提供 i18n 国际化消息访问的功能;
  • ResourcePatternResolver :所有 ApplicationContext 实现类都实现了类似于
    PathMatchingResourcePatternResolver 的功能,可以通过带前缀的 Ant 风格的资源文件路径装载 Spring 的配置文件。
  • LifeCycle:该接口是 Spring 2.0 加入的,该接口提供了 start()和 stop()两个方法,主要用于控制异步处理过程。在具体使用时,该接口同时被 ApplicationContext 实现
    及具体 Bean 实现,ApplicationContext 会将 start/stop 的信息传递给容器中所有实现了该接口的 Bean,以达到管理和控制 JMX、任务调度等目的

ConfigurableApplicationContext 扩展于 ApplicationContext,它新增加了两个主要的方法:refresh()和 close(),让 ApplicationContext 具有启动、刷新和关闭应用上下文的能力。

在应用上下文关闭的情况下调用 refresh()即可启动应用上下文,在已经启动的状态下,调用 refresh()则清除缓存并重新装载配置信息,而调用 close()则可关闭应用上下文。这些接口方法为容器的控制管理带来了便利,但作为开发者,我们并不需要过多关心这些方法;

和 BeanFactory 初始化相似,ApplicationContext 的初始化也很简单,如果配置文件放置在类路径下,用户可以优先使用 ClassPathXmlApplicationContext 实现类:

类路径名获取返回一个Spring容器
ApplicationContext ctx = new ClassPathXmlApplicationContext(“com/baobaotao/ context/beans.xml”);获取资源

番外:

对于 ClassPathXmlApplicationContext 来说,“com/baobaotao/context/beans.xml”

等同于“classpath: com/baobaotao/context/beans.xml”。

如果配置文件放置在文件系统的路径下,则可以优先考虑使用 FilySystemXml
ApplicationContext 实现类:

ApplicationContext ctx =new FileSystemXmlApplicationContext(“com/baobaotao/ context/beans.xml”);

对于FileSystemXmlApplicationContext来说,“com/baobaotao/context/beans.xml”

等同于“file:com/baobaotao/context/beans.xm

还可以指定一组配置文件,Spring会自动将多个配置文件在内存中“整合”成一个配置文件,如下

ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[]{“conf/beans1.xml”,“conf/beans2.xml”});

当然 FileSystemXmlApplicationContext 和 ClassPathXmlApplicationContext 都可以
使用带资源类型前缀的路径,它们的区别在于如果不显式指定资源类型前缀,将分别将路径解析为文件系统路径和类路径

总结一

简单介绍了一下,只要看懂流程图,基本就已经明白两者之间的区别了

第一个区别

两者实例化Bean创建不同

BeanFactory 是根接口,有一个实现类是XmlBeanFactory,可以从classpath或文件系统等获取资源。然后返回一个Bean工厂的实例,通过getBean来实例化一个资源
在这里插入图片描述

但是ApplicationContext 是通过

ApplicationContext ctx =new FileSystemXmlApplicationContext(“com/baobaotao/ context/beans.xml”);全部实例
然后通过getBean(“Car1”,Car.class)拿去获得实例

ApplicationContext在启动的时候就把所有的Bean全部实例化了。它还可以为Bean配置lazy-init=true来让Bean延迟实例化;

第二个区别

BeanFactory 作为顶级根接口,属于spring心脏,但是ApplicationContext比较来说,更加完善。区别有四

ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能:

  • a. 国际化支持
  • b. 资源访问:Resource rs = ctx. getResource(“classpath:config.properties”),
  • c. 事件传递:通过实现ApplicationContextAware接口
  • d.载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层

如果还有什么区别欢迎评论

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值