-
BeanFactory和FactoryBean,ApplicationContext的关系
- 他们的区别比较容易理解,从字面意思就能区分开来,BeanFactory是Bean工厂,而FactoryBean是工厂Bean
- BeanFactory,Spring中工厂的顶层规范,他是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖
- 它定义了getBean()、containsBean()等管理Bean的通用方法
- 这是基本的 Spring 模块,提供 Spring 框架的基础功能,BeanFactory 是 任何以Spring 为基础的应用的核心
- Spring 框架建立在此模块之上,它使 Spring 成为一个容器
- Bean 工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从真正的应用代码中分离
- 最常用的 BeanFactory 实现是 XmlBeanFactory 类
- 它根据 XML 文件中的定义加载 beans;该容器从 XML 文件读取配置元数据并用它去创建一个完全配置的系统或应用
- BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器
- 其中ApplicationContext是BeanFactory的子接口
- 依赖关系
- BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系
- ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:
- 载入多个(有继承关系)上下文,使得每一个上下文都专注于一个特定的层次,比如应用的web层
- 加载方式
- BeanFactory采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化
- 这样,我们就不能发现一些存在的Spring的配置问题
- 如果Bean的某一个属性没有注入,BeanFactory加载后,直至第一次使用调用getBean方法才会抛出异常
- ApplicationContext,它是在容器启动时,一次性创建了所有的Bean
- 这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入
- ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean,确保当你需要的时候,你就不用等待,因为它们已经创建好了
- 相对于基本的BeanFactory,ApplicationContext唯一的不足是占用内存空间
- 当应用程序配置Bean较多时,程序启动较慢
- 创建方式
- BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader
- 注册方式
- BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册
- Spring设计了两个接口用以表示容器
- BeanFactory 粗暴简单,可以理解为就是个 HashMap,Key 是 BeanName,Value 是 Bean 实例
- 通常只提供注册(put),获取(get)这两个功能,可以称之为“低级容器”
- ApplicationContext 可以称之为“高级容器”
- 因为他比 BeanFactory 多了更多的功能
- 他继承了多个接口,因此具备了更多的功能
- 例如资源的获取,支持多种消息(例如 JSP tag 的支持),对 BeanFactory 多了工具级别的支持等待
- 所以你看他的名字,已经不是 BeanFactory 之类的工厂了,而是“应用上下文”,代表着整个大容器的所有功能
- 该接口定义了一个 refresh 方法,此方法是所有阅读 Spring 源码的人的最熟悉的方法,用于刷新整个容器,即重新加载/刷新所有的bean
- 当然,除了这两个大接口,还有其他的辅助接口,但我今天不会花太多篇幅介绍他们
- 为了更直观的展示 “低级容器” 和 “高级容器” 的关系,我这里通过常用的 ClassPathXmlApplicationContext类,来展示整个容器的层级 UML 关系
- 最上面的 BeanFactory,下面的 3 个绿色的,都是功能扩展接口,这里就不展开讲
- 看下面的隶属 ApplicationContext 粉红色的 “高级容器”,依赖着 “低级容器”,这里说的是依赖,不是继承
- 他依赖着 “低级容器” 的 getBean 功能
- 而高级容器有更多的功能:支持不同的信息源头,可以访问文件资源,支持应用事件(Observer 模式)
- 通常用户看到的就是“高级容器”
- 但 BeanFactory 也非常够用;左边灰色区域的是 “低级容器”,只负载加载 Bean,获取 Bean
- 容器其他的高级功能是没有的
- 例如上图画的 refresh 刷新 Bean 工厂所有配置,生命周期事件回调等
- ApplicationContext通常的实现
- FileSystemXmlApplicationContext:此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数
- ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置
- WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean
- BeanFactory-框架基础设施
- BeanFactory是Spring框架的基础设施,面向 Spring 本身;
- ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的应用场合我们都直接使用 ApplicationContext 而非底层的 BeanFactory
- 1-BeanDefinitionRegistry 注册表
- Spring 配置文件中每一个节点元素在 Spring 容器里都通过一个 BeanDefinition 对象表示,它描述了 Bean 的配置信息
- 而 BeanDefinitionRegistry 接口提供了向容器手工注册 BeanDefinition 对象的方法
- 2-BeanFactory 顶层接口
- 位于类结构树的顶端,它最主要的方法就是 getBean(String beanName),该方法从容器中返回特定名称的 Bean
- BeanFactory 的功能通过其他的接口得到不断扩展
- 3-ListableBeanFactory
- 该接口定义了访问容器中 Bean 基本信息的若干方法
- 如查看 Bean 的个数、获取某一类型Bean 的配置名、查看容器中是否包括某一 Bean 等方法
- 4-HierarchicalBeanFactory 父子级联
- 父子级联 IoC 容器的接口,子容器可以通过接口方法访问父容器
- 通过 HierarchicalBeanFactory 接口,Spring 的 IoC 容器可以建立父子层级关联的容器体系
- 子容器可以访问父容器中的 Bean,但父容器不能访问子容器的 Bean
- Spring 使用父子容器实现了很多功能,比如在 Spring MVC 中,展现层 Bean 位于一个子容器中,而业务层和持久层的 Bean 位于父容器中
- 这样,展现层 Bean 就可以引用业务层和持久层的 Bean,而业务层和持久层的 Bean 则看不到展现层的 Bean
- 5-ConfigurableBeanFactory
- 是一个重要的接口,增强了 IoC 容器的可定制性,它定义了设置类装载器、属性编辑器、容器初始化后置处理器等方法
- 6-AutowireCapableBeanFactory 自动装配
- 定义了将容器中的 Bean 按某种规则(如按名字匹配、按类型匹配等)进行自动装配的方法
- 7-SingletonBeanRegistry 运行期间注册单例 Bean
- 定义了允许在运行期间向容器注册单实例 Bean 的方法
- 对于单实例( singleton)的 Bean 来说,BeanFactory 会缓存 Bean 实例,所以第二次使用 getBean() 获取 Bean 时将直接从 IoC 容器的缓存中获取 Bean 实例
- Spring 在 DefaultSingletonBeanRegistry 类中提供了一个用于缓存单实例 Bean 的缓存器,它是一个用 HashMap 实现的缓存器,单实例的 Bean 以beanName 为键保存在这个 HashMap 中
- 8-依赖日志框
- 在初始化 BeanFactory 时,必须为其提供一种日志框架,比如使用 Log4J,即在类路径下提供 Log4J 配置文件,这样启动 Spring 容器才不会报错
- ApplicationContext 面向开发应用
- ApplicationContext 由 BeanFactory 派生而来,提供了更多面向实际应用的功能
- ApplicationContext 继承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,在此基础上,还通过多个其他的接口扩展了 BeanFactory 的功能:
- 1-ClassPathXmlApplicationContext:默认从类路径加载配置文件
- 2-FileSystemXmlApplicationContext:默认从文件系统中装载配置文件
- 3-ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能,包括容器启动事件、关闭事件等
- 4-MessageSource:为应用提供 i18n 国际化消息访问的功能
- 5-ResourcePatternResolver:所有 ApplicationContext 实现类都实现了类似于 PathMatchingResourcePatternResolver 的功能,可以通过带前缀的 Ant 风格的资源文件路径装载 Spring 的配置文件
- 6-LifeCycle:该接口是 Spring 2.0 加入的,该接口提供了 start() 和 stop() 两个方法,主要用于控制异步处理过程;在具体使用时,该接口同时被 ApplicationContext 实现及具体 Bean 实现,ApplicationContext 会将 start/stop 的信息传递给容器中所有实现了该接口的 Bean,以达到管理和控制 JMX、任务调度等目的
- 7-ConfigurableApplicationContext 扩展于 ApplicationContext,它新增加了两个主要的方法:refresh() 和 close(),让 ApplicationContext 具有启动、刷新和关闭应用上下文的能力;在应用上下文关闭的情况下调用 refresh() 即可启动应用上下文,在已经启动的状态下,调用 refresh() 则清除缓存并重新装载配置信息,而调用 close() 则可关闭应用上下文
- Spring容器中有两种Bean:普通Bean和工厂Bean
- Spring直接使用前者,FactoryBean跟普通Bean不同,其返回的对象不是指定类的一个实例,而是该FactoryBean的getObject方法所返回的对象
- Spring通过反射机制利用的class属性指定的实现类来实例化bean
- 在某些情况下,实例化bean过程比较复杂,如果按照传统的方式,则需要在其中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到更好的效果
- Spring为此提供了一个org.Springframework.beans.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化bean的逻辑
- Spring框架本身就自带了实现FactoryBean的70多个接口,如ProxyFactoryBean、MapFactoryBean、PropertiesFactoryBean等
-
相关阅读:
MySQL聚集函数
956. 最高的广告牌
三、Zabbix — 自定义监控
如何查看 class 文件的编译器版本
tictoc例子理解 16-18
flex 布局(弹性布局 / 弹性盒子)详细教程
【利用AI让知识体系化】5种创建型模式
JAVA IO 流分类整理
Pytorch 的数据处理 学习笔记
python爬虫爬取某图书网页实例
-
原文地址:https://blog.csdn.net/weixin_59624686/article/details/133661603