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)非常有用。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【区块链】POS(Proof of Stake)权益证明算法深度解析

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 POS&#xff08;Proof of Stake&#xff09;权益证明算法深度解析引言1. POS基本…

基于Matlab的细胞计数图像处理系统(GUI界面有报告) 【含Matlab源码 MX_003期】

简介&#xff1a; 本文旨在解决生物血细胞数目统计的挑战&#xff0c;提出了基于图像处理的综合方案。通过MATLAB平台&#xff0c;我们设计并实现了一套完整的细胞图像处理与分析流程。在预处理阶段&#xff0c;采用图像增强和阈值分割等方法&#xff0c;有效地提高了细胞图像的…

Linux---rpm/yum包管理器

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.RPM概述 RPM&#xff08;Red Hat Package Manager&#xff09;是Linux中的一种软件包管理格式也可以称为软件包管理器&#xff1b;它可以将软件包以二进制形式打包&#xff0c;并提供工具来安…

Conmi的正确答案——Vue默认加载方式设置为Yarn后怎么修改

Vue版本&#xff1a;3 1和2主要是搜索文件所在位置&#xff0c;Windows的这个文件一般在“C:\Users\{当前用户}”下&#xff0c;linux的非root情况下一般在“/home/{当前用户}”下。 1、打开“Everything”&#xff1b; 2、搜索“vuerc”&#xff1b; 3、打开“.vuerc”&#…

vue 和 js写屏幕自适应

实现屏幕自适应的方式有很多种&#xff0c;可以通过插件本身提供的方法&#xff0c;可以通过flex布局等&#xff0c;今天我们来写写通过js实现屏幕自适应。 以下是在vue中实现的屏幕自适应 首先在data中定义一下屏幕的默认大小和缩放比例 然后在mounted中获取窗口的内置宽高&a…

jrt从量变到质变

又是一个加班的周末&#xff0c;上周把台式机代码和数据库环境弄好了&#xff0c;这周进行大数据测试&#xff0c;直接把标本、标本医嘱、报告、报告结果、药敏结果等数据插入到1亿的规模&#xff0c;跑了一天一夜插入了5000多万个标本&#xff0c;后面接着补剩下的到一亿。 演…

生命在于学习——Python人工智能原理(3.5)

三、深度学习 9、常见神经网络 常见的神经网络有卷积神经网络&#xff08;AlexNet、VGGNet&#xff09;、循环神经网络&#xff08;RNN&#xff09; 长短时记忆网络&#xff08;LSTM&#xff09;。 &#xff08;1&#xff09;AlexNet AlexNet于2012年由Hinton学生Alex提出&a…

shell脚本编程(概念、编程和语句)

一、shell脚本概述 1、shell脚本概念 Shell 脚本是利用 shell 的功能所写的一个程序。这个程序是使用纯文本文件&#xff0c;将一些 shell 的语法与命令&#xff08;含外部命令&#xff09;写在里面&#xff0c;搭配正则表达式、管道命令与数据流重定向等功能。 2、Shell 脚…

使用vscode插件du-i18n处理前端项目国际化翻译多语言

前段时间我写了一篇关于项目国际化使用I18n组件的文章&#xff0c;Vue3 TS 使用国际化组件I18n&#xff0c;那个时候还没真正在项目中使用&#xff0c;需求排期还没有定&#xff0c;相当于是预研。 当时就看了一下大概怎么用&#xff0c;改了一个简单的页面&#xff0c;最近需…

嵌入式实训day6

1、 from machine import Pin from neopixel import NeoPixel import timeif __name__"__main__"#创建RBG灯带控制对象&#xff0c;包含5个像素(5个RGB LED)rgb_led NeoPixel(Pin(4,Pin.OUT)&#xff0c;5)#定义RGB颜色RED(255&#xff0c;0&#xff0c;0)GREEN(0,2…

SOLIDWORKS 2024正版软件:新增功能介绍

随着科技的飞速发展&#xff0c;计算机辅助设计&#xff08;CAD&#xff09;软件在工业设计领域扮演着越来越重要的角色。SOLIDWORKS作为3D CAD软件提供商&#xff0c;其每一次版本更新都带来了一系列创新功能和改进&#xff0c;旨在为用户提供更有效、更智能、更协同的设计体验…

传输层udp和tcp协议格式

UDP协议 UDP协议端格式 udp的前八个字节是报头&#xff0c;后面部分就是有效载荷。而目的端口号就保证了udp向应用层交付的问题。 而针对于报头和有效载荷分离是根据固定八字结的报头长度。数据的长度就是取决于报头中udp长度字段的大小来确定udp报文长度&#xff0c;因此也可…

006 spring事务支持

文章目录 事务回顾事务介绍事务并发问题(隔离性导致)事务隔离级别 Spring框架事务管理相关接口Spring框架事务管理的分类编程式事务管理(了解)声明式事务管理(重点) 事务管理之XML方式业务层持久层单元测试代码配置事务管理的AOP 事务管理之混合方式事务管理之基于AspectJ的纯注…

【分布式事务】分布式事务其他解决方案——2PC

目录 2PC解释例子分析回到IT系统中 XA 方案执行流程DTP 模型交互模式 总结 2PC 解释 2PC 即两阶段提交协议&#xff0c;是将整个事务流程分为两个阶段&#xff0c;准备阶段&#xff08;Prepare phase&#xff09;、提交阶段&#xff08;commit phase&#xff09;&#xff0c;…

PyMuPDF 操作手册 - 01 从PDF中提取文本

文章目录 一、打开文件二、从 PDF 中提取文本2.1 文本基础操作2.2 文本进阶操作2.2.1 从任何文档中提取文本2.2.2 如何将文本提取为 Markdown2.2.3 如何从页面中提取键值对2.2.4 如何从矩形中提取文本2.2.5 如何以自然阅读顺序提取文本2.2.6 如何从文档中提取表格内容2.2.6.1 提…

经典sql

一、连续登录问题 问题&#xff1a;1&#xff09;、每个用户连续登录最大天数 2&#xff09;、连续登录大于三天的用户数 分析&#xff1a;本质都是计算用户连续登录天数 方案一&#xff1a;利用排序窗口 select a.user_id,a.date_rslt,count(1) as cnt from (select t.…

定个小目标之刷LeetCode热题(22)

这道题最容易想的就是排序后再遍历&#xff0c;但是时间复杂度就不是O(n)了&#xff0c;所以还是得用更优的解法&#xff0c;直接看题解&#xff0c;它是使用了HashSet&#xff0c;遍历数组&#xff0c;对于每一个数x&#xff0c;如果不存在x - 1则进入内循环&#xff0c;否则跳…

java智慧工地系统源码 智慧工地标准之一:环境监测 告别灰头土脸、智慧工地环境监测系统都包括哪些功能?

java智慧工地系统源码 智慧工地标准之一&#xff1a;环境监测 告别灰头土脸、智慧工地环境监测系统都包括哪些功能&#xff1f; 智慧工地环境监测系统是一套集成了物联网、大数据和云计算技术的系统&#xff0c;主要用于实时监测和管理建筑工地的环境状况。以下是该系统的一些核…

金融科技行业的融资趋势、投资者关注及未来预测

一、金融科技行业的融资趋势 金融科技行业的融资趋势近年来展现出强劲的增长势头&#xff0c;具体表现在以下几个方面&#xff1a; 融资规模持续扩大&#xff1a; 根据《全球金融科技投融资趋势报告(2023年上半年)》&#xff0c;2023年上半年全球金融科技行业投融资事件总次数…

语言大模型:开启自然语言处理的新篇章

随着人工智能技术的飞速发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域取得了显著的成果。其中&#xff0c;语言大模型&#xff08;Language Models&#xff09;作为近年来崛起的一种新型神经网络模型&#xff0c;已经在文本生成、机器翻译、情感分析等多个NLP任…