Bean的销毁过程

简介: Bean的销毁过程

Bean销毁是发送在Spring容器关闭过程中的。

在Spring容器关闭时,比如:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) context.getBean("userService");
userService.test();
// 容器关闭
context.close();

在Bean创建过程中,在最后(初始化之后),有一个步骤会去判断当前创建的Bean是不是DisposableBean:

  1. 当前Bean是否实现了DisposableBean接口
  2. 或者,当前Bean是否实现了AutoCloseable接口
  3. BeanDefinition中是否指定了destroyMethod
  4. 调用DestructionAwareBeanPostProcessor.requiresDestruction(bean)进行判断
  1. ApplicationListenerDetector中直接使用的是ApplicationListener的DisposableBean
  2. InitDestroyAnnotationBeanPostProcessor使用拥有@PreDestroy的注解的方法就是DisposableBean
  1. 把符合上述任意一个条件的Bean适配成DisposableBeanAdapter对象,并存入disposableBeans中(一个LinkedHashMap)

在Spring容器关闭过程时:

  1. 首先发布ContextClosedEvent事件
  2. 调用lifecycleProcessor的onCloese()方法
  3. 销毁单例Bean
  1. 把每个disposableBean从单例池中移除
  2. 调用disposableBean的destroy()
  3. 如果这个disposableBean还被其他Bean依赖了,那么也得销毁其他Bean
  4. 如果这个disposableBean还包含了inner beans,将这些Bean从单例池中移除掉 (inner bean参考https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-inner-beans)
  5. 遍历disposableBeans
  6. 清空manualSingletonNames,是一个Set,存的是用户手动注册的单例Bean的beanName
  7. 清空allBeanNamesByType,是一个Map,key是bean类型,value是该类型所有的beanName数组
  8. 清空singletonBeanNamesByType,和allBeanNamesByType类似,只不过只存了单例Bean

这里涉及到一个设计模式:适配器模式

在销毁时,Spring会找出实现了DisposableBean接口的Bean。

但是在定义一个Bean时,如果这个Bean实现了DisposableBean接口,或者实现了AutoCloseable接口,或者在BeanDefinition中指定了destroyMethodName,那么这个Bean都属于“DisposableBean”,这些Bean在容器关闭时都要调用相应的销毁方法。

所以,这里就需要进行适配,将实现了DisposableBean接口、或者AutoCloseable接口等适配成实现了DisposableBean接口,所以就用到了DisposableBeanAdapter。

会把实现了AutoCloseable接口的类封装成DisposableBeanAdapter,而DisposableBeanAdapter实现了DisposableBean接口。

目录
相关文章
|
2月前
|
Java 容器 Spring
Bean的实例化阶段
经过第一阶段,所有bean定义都通过BeanDefinition的方式注册到BeanDefinitionRegistry中当某个请求通过容器的getBean方法请求某个对象,或者因为依赖关系容器需要隐式的调用getBean时,就会触发第二阶段的活动:容器会首先检查所请求的对象之前是否已经实例化完成。 如果没有,则会根据注册的BeanDefinition所提供的信息实例化被请求对象,并为其注入依赖。 当该对象装配完毕后,容器会立即将其返回给请求方法使用。BeanFactory只是Spring IoC容器的一种实现,如果没有特殊指定,它采用采用延迟初始化策略:只有当访问容器中的某个对象时,才对
|
3月前
|
XML Java 数据格式
必知必会的13个Bean生命周期处理机制:深入理解与实践
【10月更文挑战第15天】在Spring框架中,Bean的生命周期是一个至关重要的概念,它涵盖了从Bean的创建、初始化、使用到销毁的全过程。对于一名资深的架构师而言,深入理解和掌握Bean生命周期的每一个处理机制,是构建健壮、高效和可维护应用程序的基础。本文将详细介绍Bean生命周期的13个处理机制,并通过实战demo示例来加深理解。
42 1
|
6月前
|
Java Spring
Spring初始化加速的思路和方案问题之在BeanFactory#doGetBean方法中,栈状态的变化影响bean的初始化的问题如何解决
Spring初始化加速的思路和方案问题之在BeanFactory#doGetBean方法中,栈状态的变化影响bean的初始化的问题如何解决
|
6月前
|
Java Spring 容器
循环依赖问题之实例化Bean是通过如何实现的
循环依赖问题之实例化Bean是通过如何实现的
|
8月前
|
Java 容器 Spring
SpringBoot:Bean生命周期自定义初始化和销毁
SpringBoot:Bean生命周期自定义初始化和销毁
198 1
|
8月前
将生命周期方法添加到类中
将生命周期方法添加到类中
|
容器
IOC容器初始化过程中单例Bean的预实例化
IOC容器初始化过程中单例Bean的预实例化
60 0
|
XML Java 数据格式
延迟初始化Bean会影响依赖注入吗
延迟初始化Bean会影响依赖注入吗
63 0
|
中间件 Java
Bean异步初始化
Bean异步初始化
|
Java 容器 Spring
【Spring 源码学习系列】Bean 的生命周期之初始化与销毁
本文将结合一个简单案例,学习 Bean 生命周期中的初始化和销毁阶段的具体内容。
306 0
【Spring 源码学习系列】Bean 的生命周期之初始化与销毁