Spring Bean到底是如何创建的?(下)

简介: Spring Bean生命周期继续回顾

大家好,我是三友~~

本文是接着上篇文章 Spring bean到底是如何创建的?(上) 来继续讲述spring bean的其它的生命周期。

前文回顾

上篇文章最开始我简单介绍了spring ioc和aop的概念,随后讲述了spring bean创建源码分析的一部分,包括bean元信息、不同作用域bean的创建方式、bean的后置处理器BeanPostProcessor组件体系、三级缓存解决循环依赖的问题、bean 的实例化阶段的源码。接下来这篇会继续从源码的角度来分析bean生命周期的其它阶段,包括 bean属性赋值阶段、Aware接口回调阶段、bean初始化阶段、bean的销毁阶段的内容。

公众号:三友的java日记

Spring Bean属性赋值阶段

1)属性赋值前阶段

这个阶段需要对bean的一些属性进行赋值。比如说@Autowired 、@Resource等注解都是在这个阶段生效的。

image.png

PropertyValues:这个api是封装属性的。不知道大家记不记得,当用xml配置bean的时候是可以通过标签给属性赋值的,其实当spring对配置信息解析之后会封装在PropertyValues中。

image.png

看看,这里其实有又是对BeanPostProcessor组件接口的回调。@Autowired 、@Resource 注解就是在这时生效的。

我给大家列举一下在这个阶段一些重要的实现类,大家有时间可以翻一下源码,自己阅读一下这些实现类的 postProcessProperties 方法,看看注解是怎么生效的。

  • AutowiredAnnotationBeanPostProcessor:处理@Autowired、@Value注解
  • CommonAnnotationBeanPostProcessor:这个类的功能比较多,主要是实现了 @PostConstruct 、@PreDestory 、 @Resource 注解的功能,当然是在不同的阶段生效的,只不过spring 都给他写在同一个类中了

除了spring的实现,你还可以自己实现postProcessProperties ,因为你看这个方法的返回值是 PropertyValues ,属性的封装,所以可以在方法实现的时候往 PropertyValues 添加一些数据,这样就给属性赋值的时候就按照你设置的属性来赋值了。

2)属性赋值阶段

继续往下走

image.png

这里会给属性赋值,所谓的赋值其实很简单,就是从 PropertyValues 拿出配置的属性以及对应的属性的值,然后设置到属性中其实就行了。只不过这里可能涉及到一些类型的转换和占位符的解析,还有一些其它的特性,这里就不详细展开讲了。

Aware接口回调阶段

这个阶段主要是会判断你有没有实现某些Aware接口,如果你实现了的话,spring会调用这些接口。

populateBean方法结束了,接下来进入initializeBean方法

image.png

进入 invokeAwareMethods方法

image.png

image.png

当你的bean实现了这些接口,spring会回调你的bean这些接口的实现

Spring Bean初始化阶段

属性赋值完和Aware接口回调完之后,会进入对象的初始化阶段

1)初始化之前阶段

image.png

image.png

其实也还是BeanPostProcessor方法的回调

这里有一个实现类,叫 ApplicationContextAwareProcessor,这个类跟上面Aware回调阶段干的事差不多,其实就是判断你有没有实现哪些接口,如果实现了,就会回调你实现接口的方法。

2)初始化阶段

接下来进入invokeInitMethods方法

image.png

image.png

这里进行了bean的初始化,就是如果你的bean实现了InitializingBean接口或者你配置了自定义的initMethod(xml中有属性可以配置,@Bean注解的initMethod属性配置),这里就会回调你的方法

3)初始化之后阶段

image.png

image.png

这些阶段继续回调BeanPostProcessor方法,其实在这个阶段,就完成了对于对象的动态代理的生成,具体是由 AspectJAwareAdvisorAutoProxyCreator 这个实现完成的,大家可以自己翻一下这个实现类的postProcessAfterInitialization方法,是在这个类的父类中实现的。

到这里为止,一个单例的bean就被完完整整的给创建出来了,你平时使用的对象也就是这个对象。

接下来就是将对象放在 singletonObjects 缓存中,如果下次有查询的话,就直接从这个缓存中查找出来返回(上一篇文章说过,先查询,如果查不到再创建)。

Spring Bean销毁阶段

这个阶段不属于bean的创建阶段,你平时使用的bean在上一个阶段就完完全全创建好了,这个阶段是在spring容器关闭的时候才会执行。

1)DisposableBean的注册

接下来继续往下走

image.png

image.png

这个阶段就是将bean给包裹成一个DisposableBean,也就是DisposableBeanAdapter对象,给放到disposableBeans中,但是要想放到disposableBeans中是要有条件的,比如你实现了DisposableBean接口,或者在xml中配置销毁的方法名或通过@Bean的属性的destoryMethod方法中指定了方法名等,具体的条件可以进入hasDestroyMethod方法中查看

2)bean 销毁前阶段

spring bean 什么时候会销毁?

当项目停止的时候,会回调ApplicationContext的close()方法(是由AbstractApplicationContext实现的),这个回去调用doClose()方法,doClose()方法会去回调BeanFactory(由DefaultListableBeanFactory实现)的destroySingleton方法,然后回调用父类DefaultSingletonBeanRegistry方法,从这开始就开始就进行单例bean的销毁。

我们直接定位到DefaultSingletonBeanRegistry的destroySingleton方法

image.png

根据bean名称从disposableBeans中取出上面注册的DisposableBean,然后调用destroyBean方法

image.png

这里我们可以看出,是直接调用我们注册的DisposableBean,也就是DisposableBeanAdapter事件的destroy方法,接下来我们进入destroy方法

image.png

这里就是又是BeanPostProcessor组件方法的回调

3)bean的销毁阶段

image.png

如果我们自己的bean是实现了DisposableBean接口,那么spring会回调这个方法的实现

接下来就是回调我们配置的销毁的回调方法

image.png

至此,bean就被销毁了。

全文总结

到这里整个spring bean生命周期源码分析就完全讲完了,包括了bean创建和销毁,其实bean的生命周期说白了就是在bean创建和销毁的不同阶段进行BeanPostProcessor组件方法的回调来达到对于bean的创建或销毁过程扩展的目的。其实我们自己也可以在项目中实现BeanPostProcessor接口来达到自己的目的。在讲述spring bean的生命周期的时候,我也提到了bean的作用域、spring是如何使用三级缓存解决循环依赖等问题。相信这两篇文章看完之后大家对spring bean创建和销毁的过程都有一个全面的了解。

思考题

你知道spring还有哪些功能是通过扩展BeanPostProcessor来实现的么?除了spring之外有哪些框架是通过扩展BeanPostProcessor实现跟spring整合的?

公众号:三友的java日记

相关文章
|
12天前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
1月前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
67 9
Spring从入门到入土(bean的一些子标签及注解的使用)
|
2月前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
205 24
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
1月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
2月前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
212 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
2月前
|
XML Java 数据格式
spring复习02,xml配置管理bean
详细讲解了Spring框架中基于XML配置文件管理bean的各种方式,包括获取bean、依赖注入、特殊值处理、属性赋值、集合类型处理、p命名空间、bean作用域及生命周期和自动装配。
spring复习02,xml配置管理bean
|
1月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
77 1
|
1月前
|
Java Spring
获取spring工厂中bean对象的两种方式
获取spring工厂中bean对象的两种方式
38 1
|
1月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细介绍了Spring框架中的核心概念——Spring Bean的生命周期,包括实例化、属性赋值、接口回调、初始化、使用及销毁等10个阶段,并深入剖析了相关源码,如`BeanFactory`、`DefaultListableBeanFactory`和`BeanPostProcessor`等关键类与接口。通过理解这些核心组件,读者可以更好地掌握Spring Bean的管理和控制机制。
84 1
|
2月前
|
XML Java 数据格式
spring复习03,注解配置管理bean
Spring框架中使用注解配置管理bean的方法,包括常用注解的标识组件、扫描组件、基于注解的自动装配以及使用注解后的注意事项,并提供了一个基于注解自动装配的完整示例。
spring复习03,注解配置管理bean