介绍 Spring 体系、Bean 生命周期剖析以及核心接口 BeanFactory、BeanFactoryPostProcessor、BeanPostProcessor

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 介绍 Spring 体系、Bean 生命周期剖析以及核心接口 BeanFactory、BeanFactoryPostProcessor、BeanPostProcessor

Spring 体系初识

在 Spring 中核心是 IOC(Inverse of Control) 控制反转、 AOP(Aspect Oriented Programming) 面向切面编程

  1. IOC:不再由自己控制这个对象的创建,而是交由给 Spring 去控制这个内置对象的创建
  2. DI(依赖注入)「Dependency Injection」:自身对象是通过注入的方式进行创建,DI 是 IOC 功能的具体实现,依赖注入可以通过 setter 方法注入(设值注入)、构造函数注入、接口注入三种方式实现,Spring 支持 setter 注入和构造注入,通常使用构造器来注入必须的依赖关系;对于支持可选的依赖关系,推荐使用 setter 注入方式是更好的选择,setter 注入需要类提供无参构造器或者无参的静态工厂方法来创建对象
  3. AOP:通过预编译方式和运行期动态代理方式实现代码增强的一种技术

Bean 生命周期剖析

通过以下这张图流程图来了解 spring 整个生命周期

创建了 BeanFactory 工厂对象,是整个容器的根接口,也是入口;我们实际上使用的是它的子类「DefaultListableBeanFactory」具体的容器对象都是使用反射机制来获取到类实例的.

BeanFactory 和 ApplicationContext 区别

BeanFactory:spring 容器的根/顶层接口,主要是为我们管理获取 bean 实例和 bean 创建

ApplicationContext:属于 BeanFactory 子接口,在原有功能基础上,为我们扩展了一些新的功能->国际化语言支持、资源加载工作、发布事件

Bean 可以通过不同的方式进行定义:xml、properties、yaml、json,对应的需要一些解析器能够对它们进行解析且转换成我们所能识别的 bean 对象,通过 BeanDefinitionReader 来进行读取将其转换为 BeanDefinition 对象,再通过反射的机制获取到 Bean 实例,最后进行一系列填充和增强类的操作

BeanFactoryPostProcessor「BFPP」:调用所有实现 BFPP 接口的类方法,在这里会做注解的解析工作,如:@Component、@ComponentScan、@Import,对应的解析类是 ConfigurationClassPostProcessor、其次还会在这里还会所有占位符的变量进行赋值操作,方便后续在类填充属性阶段可以直接取到所配置的值,对应的解析类是 PropertySourcesPlaceholderConfigurer

作好实例化前的准备工作以后,Bean 生命周期会经历以下的几个过程,形成一个完整的对象,如下:

  1. 实例化「createBeanInstance」:创建 bean 实例对象,通过反射调用构造函数获取.
  2. 填充属性「populate」:实例化后的对象里面属性都是赋予的默认值,在此阶段会为其赋予初始值
  3. 初始化阶段分为以下几个过程:

1、invokeAwareMethods:执行 aware 方法,设置相关的信息,普通 bean 都会执行三个 aware 接口->BeanNameAware、ClassLoaderAware、BeanFactoryAware

2、BPP#before「Spring 提供的扩展点」:执行实现 BeanPostProcessor 接口子类的前置方法,除了以上三个 aware 接口之外,其他的如果有实现对应的 aware 都是会在 ApplicationContextAwareProcessor 类中进行调用执行的

3、invokeInitMethods:如果该 bean 有实现 InitializingBean 接口,则会调用其实现的 afterPropertiesSet 方法;再者如果该 bean 有自定义的 initMethod 方法,有的话则通过反射调用执行

4、BPP#after:执行实现 BeanPostProcessor 接口子类的后置方法

5、完成以上步骤以后,该 bean 加载工作就算完成了,可以通过 context.getBean() 进行调用了

  1. 当 bean 使用完成以后,就要进行销毁工作了,也分为几步进行

如果当前 BPP 集合存在接口 DestructionAwareBeanPostProcessor,会挨个遍历调用其 postProcessBeforeDestruction 方法

如果当前 bean 有实现 DisposableBean 接口,则会调用其实现的 destroy 方法;再者如果该 bean 有自定义的 destroy 方法,有的话通过反射进行调用

实例化和初始化区别

FactoryBean、BeanFactory 区别

相同点:都是用来创建对象的

不同点:

  1. BeanFactory:使用它创建对象必须遵循完整的创建过程,这个生命周期是由 Spring 来管理的
  2. FactoryBean:在创建实际的对象之前,实现 FactoryBean 接口的子类优先被创建后再调用 getObject 方法创建具体的对象,整个对象的创建过程是由用户自己来控制的,更加灵活

核心接口

  1. BeanFactory:Spring 工厂的根接口、容器的入口
  2. Aware:感知,一系列 Aware 接口,通过实现它可以获取 Spring 容器内指定的对象,来满足当前的程序需要,在公司里,在某一个对象构建程序逻辑时,需要用到其他对象,会使用一个工具类来实现 ApplicationContextAware
  3. BeanDefinitionReader:定义资源文件读取并转换为 BeanDefinition 的各个功能
  4. BeanFactoryPostProcessor:后置处理增强器,允许自定义修改应用程序上下文的 BeanDefinition 信息
  5. BeanPostProcessor:Bean 后置处理器接口,在依赖注入的初始化方法前后进行调用,用于增强 bean
  6. Environment:当前程序允许的环境信息,一般程序上使用到的都是它的子类,标准环境对象「StandardEnviroment:获取环境源信息」、System.getProperties「JVM 系统环境属性」、System.getEnv「系统环境属性」
  7. FactoryBean:顶级接口,下层有 isSingleton(是否是单例)、getObject(获取具体对象实例)、getObjectType(获取对象的类型) 方法.

总结

该篇博文,阐述了整个 Bean 生命周期简要的流程,以及面试中常用的一些面试题:实例化和初始化区别、BeanFactory 和 FactoryBean 接口区别,最后整理了一些 Spring 核心的一些接口

如果觉得博文不错,关注我 vnjohn,后续会有更多实战、源码、架构干货分享!

大家的「关注❤️ + 点赞👍 + 收藏⭐」就是我创作的最大动力!谢谢大家的支持,我们下文见!

目录
相关文章
|
24天前
|
XML Java 数据格式
探索Spring之利剑:ApplicationContext接口
本文深入介绍了Spring框架中的核心接口ApplicationContext,解释了其作为应用容器的功能,包括事件发布、国际化支持等,并通过基于XML和注解的配置示例展示了如何使用ApplicationContext管理Bean实例。
48 6
|
1月前
|
XML 安全 Java
|
10天前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
10天前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
16天前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
53 6
|
18天前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
80 3
|
2月前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
1月前
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
34 1
|
3月前
|
存储 安全 Java
|
3月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
256 2