Spring是如何设计IOC容器的?BeanFactory ApplicationContext

BeanFactory是Spring框架中最底层的接口,用于实例化、配置和管理bean。它使用控制反转(IOC)模式,将对象的创建、管理和装配的职责从应用程序代码中转移给Spring容器。这样,应用程序代码就无需关心对象如何创建和装配,只需从容器中获取所需的对象即可。关于BeanFactory和Bean的实例化,有几点需要明确:

  1. 延迟初始化:BeanFactory默认采用延迟初始化的策略。这意味着当你创建一个BeanFactory实例时,它并不会立即实例化容器中定义的所有Bean。相反,它会等待直到某个Bean第一次被请求时,才会实例化该Bean。这种策略可以提高应用程序的启动速度,因为不是所有的Bean在启动时就都需要被实例化。
  2. 依赖注入:当BeanFactory被要求实例化一个Bean时,它会查看该Bean的依赖关系,并根据配置自动装配这些依赖。这通常通过自动装配(如通过构造函数、setter方法或字段注入)或手动装配(在XML配置文件中或通过Java配置类指定)来完成。
  3. 作用域:Spring容器中的Bean有不同的作用域(如单例、原型、请求、会话等)。BeanFactory会根据Bean的作用域来决定如何实例化和管理Bean。例如,单例Bean在整个容器生命周期内只会被实例化一次,而原型Bean每次被请求时都会实例化。
  4. 生命周期管理:除了实例化和依赖注入外,BeanFactory还负责管理Bean的生命周期。BeanPostProcessor 与 BeanFactoryPostProcessor 。

Spring 设计了两个接口用以表示容器:BeanFactory && ApplicationContext。BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。

1、BeanFactory 就是个 HashMap,Key 是 beanName,Value 是 Bean 实例。Spring里面最底层的接口:读取bean配置文档,包含了各种Bean的定义,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。我们可以称之为 “低级容器”。
ApplicationContext 可以称之为 “高级容器”,是 Spring 应用上下文。他继承了多个接口,因此具备了更多的功能:

1、EnvironmentCapable:为applicationContext声明了获取激活profile、默认profile 方法的功能,也即Environment这个接口代表应用运行时的环境。
2、MessageSource:支持消息的参数化和国际化
3、ApplicationEventPublisher:事件发布
4、ResourcePatternResolver:统一的资源文件访问方式
5、ListableBeanFactory:继承了BeanFactory,实现了枚举方法列举出当前BeanFactory中所有的bean对象而不必根据name一个一个的获取。
6、HierarchicalBeanFactory:是一个具有层级关系的Bean 工厂,拥有属性parentBeanFactory:当获取 Bean对象时,如果当前BeanFactory中不存在对应的bean,则会访问其直接 parentBeanFactory 以尝试获取bean 对象。载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。

2、BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。

ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。

相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。

3、BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:在BeanFactory中,需要手动注册BeanPostProcessor和BeanFactoryPostProcessor。这意味着开发者需要显式地在代码中调用相关方法来完成注册过程。相比之下,ApplicationContext会自动注册BeanPostProcessor和BeanFactoryPostProcessor。这意味着开发者无需显式注册这些后处理器,Spring容器会在启动时自动完成这一过程。

在Spring框架中,BeanFactoryPostProcessor 是一个特殊的bean,允许你在Spring容器实例化bean之前修改或定制应用上下文中的bean定义。BeanFactoryPostProcessor 的主要应用场景包括添加或修改bean的属性、修改bean之间的依赖关系等。

在Spring容器的初始化过程中,特别是在refresh()方法中,会调用invokeBeanFactoryPostProcessors()方法来执行所有的BeanFactoryPostProcessor。下面是invokeBeanFactoryPostProcessors()方法的基本逻辑概述:

  1. 检测BeanFactoryPostProcessor bean:Spring首先会检查容器中已经注册的所有bean定义,找出所有实现了BeanFactoryPostProcessor接口的bean。
  2. 实例化BeanFactoryPostProcessor bean:对于检测到的每一个BeanFactoryPostProcessor bean,Spring会实例化它们。但是,因为BeanFactoryPostProcessor本身也是bean,所以它们的实例化也会受到Spring的生命周期管理。
  3. 排序:如果BeanFactoryPostProcessor实现了Ordered接口或标记了@Order注解,那么Spring会按照定义的顺序来调用它们。此外,如果BeanFactoryPostProcessor实现了PriorityOrdered接口,那么这些bean会具有更高的优先级,并在普通的Ordered bean之前被调用。
  4. 调用postProcessBeanFactory方法:对于每一个BeanFactoryPostProcessor实例,Spring会调用其postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法。这个方法允许你修改或定制传入的ConfigurableListableBeanFactory,这个对象代表了Spring IoC容器当前的内部状态。
  5. 继续容器初始化:在所有BeanFactoryPostProcessor被调用并处理完毕后,Spring容器会继续其初始化过程,包括实例化、依赖注入、调用初始化方法等步骤。

通过BeanFactoryPostProcessor,你可以获得对Spring IoC容器内部状态的控制,并在bean实例化之前修改bean定义。这种能力使得BeanFactoryPostProcessor在Spring的扩展性和灵活性方面发挥了重要作用。

在Spring框架中,BeanPostProcessor接口允许开发者在Spring IoC容器实例化bean后、初始化方法(如果有的话)调用前和调用后插入自定义的逻辑。这是Spring AOP(面向切面编程)功能的一部分,虽然BeanPostProcessor本身并不直接实现AOP,但它为AOP提供了基础。

以下是BeanPostProcessor在Spring中使用的步骤:

  1. 定义BeanPostProcessor:你需要实现BeanPostProcessor接口,并重写postProcessBeforeInitialization和postProcessAfterInitialization方法。这两个方法分别在bean的初始化方法(如@PostConstruct注解的方法或实现了InitializingBean接口中的afterPropertiesSet方法)调用之前和之后被调用。
public class CustomBeanPostProcessor implements BeanPostProcessor {  @Override  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {  // 在bean的初始化方法之前执行的逻辑  System.out.println("Before initialization: " + beanName);  return bean;  }  @Override  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  // 在bean的初始化方法之后执行的逻辑  System.out.println("After initialization: " + beanName);  return bean;  }  
}
  1. 注册BeanPostProcessor:将你的BeanPostProcessor实现注册到Spring容器中。这可以通过XML配置或Java配置完成。
<bean class="com.example.CustomBeanPostProcessor" />
@Configuration  
public class AppConfig {  @Bean  public CustomBeanPostProcessor customBeanPostProcessor() {  return new CustomBeanPostProcessor();  }  // ... 其他bean的定义 ...  
}
  1. 使用:一旦BeanPostProcessor被注册到容器中,Spring就会在创建并初始化每个bean时自动调用它。你不需要在代码中显式地调用BeanPostProcessor。需要注意的是,BeanPostProcessor自身也会被当作一个bean来处理,这意味着BeanPostProcessor也会受到BeanPostProcessor链的影响。因此,在定义多个BeanPostProcessor时,需要注意它们之间的依赖关系和初始化顺序。

通过BeanPostProcessor,你可以对Spring容器中的bean进行拦截,并在bean的生命周期中的关键点上添加自定义逻辑。这对于诸如日志记录、安全检查、性能监控等横切关注点(cross-cutting concerns)非常有用。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/29475.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何配置docker通过代理服务器拉取镜像

如果 docker 所在的环境是通过代理服务器和互联网连通的&#xff0c;那么需要一番配置才能让 docker 正常从外网正常拉取镜像。然而仅仅通过配置环境变量的方法是不够的。本文结合已有文档&#xff0c;介绍如何配置代理服务器能使docker正常拉取镜像。 本文使用的docker 版本是…

【vue3】vue3中使用reactive定义的变量响应式丢失问题

这里写目录标题 1. 解构响应式对象属性2. 添加新属性到响应式对象3. 异步更新响应式状态4.总结 当你说“vue3中使用reactive定义的变量响应式丢失问题”时&#xff0c;以下是一些更具体的例子和解决方案&#xff1a; 1. 解构响应式对象属性 问题&#xff1a; import { reacti…

Django里的模板变量

变量是模板中最基本的组成单位&#xff0c;是视图传递给模板的数据&#xff1b; 当模板引擎遇到变量时&#xff0c;会将该变量计算为结果&#xff1b; 变量以{{variable}}表示&#xff0c;如&#xff1a; obj{“name”:“张三”&#xff0c;“age”:18} {{obj.name}} #输出 …

Python网络安全项目开发实战,如何看清Web攻击

注意:本文的下载教程,与以下文章的思路有相同点,也有不同点,最终目标只是让读者从多维度去熟练掌握本知识点。 下载教程: Python网络安全项目开发实战_看清Web攻击_编程案例解析实例详解课程教程.pdf 一、引言 在网络安全领域,Web攻击一直是一个严峻的问题。攻击者通过各…

卡本医疗VENUS登陆香港国际医疗展,探索全球医疗发展新机遇

由香港贸易发展局主办的第15届香港国际医疗及保健展、以及联合香港特别行政区政府举办的第四届亚洲医疗健康高峰论坛在中国香港圆满落幕。 香港国际医疗及保健展是亚太地区最具影响力的B2B医疗贸易展览会之一&#xff0c;辐射海内外市场&#xff0c;本次邀请了超过8500家买家以…

模型部署onnx入门

一、定义 1.定义 2. 环境安装 3. 案例 4. 可视化界面 5. 参考网址 6. 推理引擎 onnx Runtime 进行单张图片推理&#xff0c;本地部署 7. 推理引擎onnx Runtime 进行单张图片推理&#xff0c;调用摄像头获取画面 8. 推理引擎onnx Runtime 进行图片推理&#xff0c;调用摄像头获…

美国原装二手KEITHELY2410替代新品keithley2470数字源表

Keithley 2470 高压 SourceMeter 源测量单元 (SMU) 仪器将先进的 Touch, Test, Invent 技术带到您的指尖。它将创新的图形用户界面 (GUI) 与电容式触摸屏技术相结合&#xff0c;使测试变得直观&#xff0c;并最大限度地缩短学习曲线&#xff0c;帮助工程师和科学家更快地学习、…

【字符串解析】IP地址字段解析提取函数接口

在嵌入式业务逻辑中&#xff0c;我们有时需要从配置文件、串口或者服务端接收的消息数据中进行字符串解析&#xff0c;来提取需要的目标字符串字段。通常我们会调用字符串处理相关的函数&#xff0c;例如strstr&#xff0c;strchr&#xff0c;sscanf等&#xff0c;再结合指针偏…

数据驱动决策:工单统计工具如何赋能企业精准运营

在当今这个数字化飞速发展的时代&#xff0c;企业对于内部运营效率的追求已经达到了前所未有的高度。你是否曾为了繁杂的工单统计管理而头疼不已&#xff1f;是否曾因为无法准确进行工单统计数据而错失商机&#xff1f;今天&#xff0c;我将向你展示一款革命性的工单统计工具&a…

Web前端经验汇总:深入探索与实战心得

Web前端经验汇总&#xff1a;深入探索与实战心得 在数字化时代的浪潮中&#xff0c;Web前端技术作为连接用户与互联网世界的桥梁&#xff0c;其重要性日益凸显。作为一名长期奋战在Web前端领域的开发者&#xff0c;我积累了一些宝贵的经验&#xff0c;并愿意在此与大家分享。 …

MBR40100CT-ASEMI无人机专用MBR40100CT

编辑&#xff1a;ll MBR40100CT-ASEMI无人机专用MBR40100CT 型号&#xff1a;MBR40100CT 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;40A 最大循环峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;100V…

TypeScript中的枚举

在 TypeScript&#xff08;TS&#xff09;中&#xff0c;枚举&#xff08;Enum&#xff09;是一种特殊的数据类型&#xff0c;它允许我们为一组命名的数值&#xff08;称为枚举成员或枚举项&#xff09;定义常量集。TypeScript 中的枚举是 TypeScript 语言扩展的一部分&#xf…

el-date-picker中popper-class的使用,自定义时间框的弹出位置

el-date-picker中popper-class的使用,自定义时间框的弹出位置 问题解决方法 问题 有时候时间选择框会根据位置自动计算出现的位置.但有时会造成被遮挡的问题使用popper-class自定义时间弹框样式不生效问题 解决方法 使用popper-class时 不要放在<style scoped></st…

【数据分析】线性及逻辑回归模型和Python实现

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 Python 初阶 Python–语言基础与由来介绍 Python–…

深入了解python函数与函数内存使用

函数的定义 函数作为代码复用的基本单元&#xff0c;可以帮助我们组织代码、减少重复、提高可读性和可维护性。 在 Python 中&#xff0c;函数本质上是对象&#xff0c;可以赋值给变量、存储在数据结构中、作为参数传递和返回。 函数与内存 函数的加载和调用过程中&#xff…

冒泡排序、选择排序

冒泡排序 按照冒泡排序的思想&#xff0c;我们要把相邻的元素两两比较&#xff0c;当一个元素大于右侧相元素时&#xff0c;交换它们的位置&#xff1b;当一个元素小于或等于右侧相邻元素时&#xff0c;位置不变 大的往右丢&#xff08;往下沉&#xff09;&#xff0c;小的往…

移动应用开发大作业报告

1 基本信息 1.1 系统名称 中华字典 1.2 开发运行环境 开发环境&#xff1a;Windows 10 专业版&#xff0c;JDK 1.8&#xff0c;AndroidStudio 运行环境&#xff1a;Java SE Runtime Environment (JRE) 8 1.3 使用的核心技术 JFrame&#xff1a;作为实现界面的窗体类&…

2024大数据面试题汇总(更新中。。。)

技术一、JAVA 技术二、hadoop 1.hadoop及其组件 Hadoop是一个开源分布式计算平台架构,基于apache协议发布,由java语言开发。主要包括 HDFS(分布式文件管理系统) MapReduce(分布式计算框架) Yarn(资源管理器) 2.NameNode与SecondaryNameNode的区别与联系 区别 1)NameNode存储…

【数据结构与算法】最小生成树

文章目录 最小生成树&#xff08;MST&#xff09;定义 构造最小生成树Prim算法Kruskal算法 最小生成树&#xff08;MST&#xff09; 连通图的生成树包含图的所有顶点&#xff0c;并且只含有尽可能少的边。对于生成树来说&#xff0c;若砍去它的一条边&#xff0c;则会使生成树…

练习时长 1 年 2 个月的 Java 菜鸡练习生最近面经,期望25K

面经哥只做互联网社招面试经历分享&#xff0c;关注我&#xff0c;每日推送精选面经&#xff0c;面试前&#xff0c;先找面经哥 自我介绍&#xff1a;本人是练习时长 1 年 2 个月的 Java 后端菜鸡练习生。下面是我最近面试的面经&#xff1a; 百度 一面 约1h时间&#xff1a;2…