历史文章(累计400+篇文章)
扩展点系列之SmartInstantiationAwareBeanPostProcessor确定执行哪一个构造方法 - 432篇
扩展点系列之ApplicationContextAwareProcessor普通类获取Spring Bean - 第433篇
扩展点系列之初始化之@PostConstruct、init-method、InitializingBean - 第434篇
SpringBoot/Spring扩展点系列之FactoryBean让你不在懵逼 - 第435篇
SpringBoot/Spring扩展点系列之SmartInitializingSingleton - 第436篇
扩展点系列之CommandLineRunner和ApplicationRunner实现缓存预热 - 第437篇
悟纤:师傅,你看哦,我想在Spring销毁的时候做些内存销毁,我应该怎么做呐?
师傅:巧了,今天我正要讲一下初始化和销毁的3种办法。
悟纤:师傅,那真是太好了,讲完了我刚好就可以用上了。
师傅:徒儿,你知道,对于技术学好的学习方法是什么?
悟纤:我想应该就是实践吧。
师傅:对,如果你要快速的掌握一个技术点,那么最好的方式就是在实际项目中进行实践使用,这样项目能够倒逼你来深入的学习技术。
悟纤:实践出真知,践践更聪明。
师傅:你又贫嘴了,你这话会让人误解~实践出真知,磨炼长才干。
师傅:
读万卷书不如行万里路,
行万里路不如阅人无数,
阅人无数不如名师指路,
名师指路不如贵人相助。
悟纤:师傅,你不仅是我的名师,还是我的贵人,那我不得起飞了~ 我要飞的更高,飞的更高。
师傅:飞的太高,摔得更疼….
导读
有时需要在 Bean 属性值 set 好之后和 Bean 销毁之前做一些事情,比如检查 Bean 中某个属性是否被正常的设置好值。Spring 框架提供了多种方法,让我们可以在 Spring Bean 的生命周期中执行 initialization 和 pre-destroy 方法,比如我们做一些数据的加载执行,链接注册中心暴漏RPC接口以及在Web程序关闭时执行链接断开,内存销毁等操作。
一、初始化和销毁方法概述
1.1 3种实现方式
(1)第一种,通过 @PostConstruct 和 @PreDestroy 方法 实现初始化和销毁 bean 之前进行的操作。
(2)第二种,通过 在 xml 中定义 init-method和 destory-method 方法。
(3)第三种,通过 bean 实现 InitializingBean和DisposableBean 接口。
说明:方式1和2,可以算是一种,只是不同的写法而已。
1.2 对Spring版本的要求
(1)xml和实现接口的方式是Spring最原始的方式,Spring任何版本均支持
(2)@PostConstruct和@PreDestroy需要Spring2.5及以上版本
(3)@bean :需要Spring 3.0以上版本支持
1.3 执行顺序不一样
先看下Spring中bean生命周期:
可以看出先后的执行顺序如下:
(1)初始化之后执行顺序: @PostConstruct > InitializingBean > Bean init-method(xml注解或者@Bean)
(2)销毁之前执行顺序:@preDestroy > DisposableBean > destroy-method(xml注解或者@Bean)
二、初始化和销毁的扩展方式
对于初始化部分的代码查看之前的文章:
《扩展点系列之初始化之@PostConstruct、init-method、InitializingBean - 第434篇》
在这里我们主要看一下销毁的扩展方式。
2.1 @PreDestroy
注解@PreDestroy是javax里定义的,属于JSR-250规范的一部分。
注: @PreDestroy已经从jdk 11版本开始移除了,所以在使用时需要额外引入javax.annotation-api:
<dependency>
<groupId>javax.annotationgroupId>
<artifactId>javax.annotation-apiartifactId>
<version>1.3.2version>
dependency>
使用方法就是类的方法上添加注解@PreDestroy,那么是否允许注解多个方法呢?答案是可以的,看如下执行效果:
具体的代码如下:
/**
* 使用@PreDestroy
*/
@PreDestroy
public void preDestroy(){
System.out.println("DemoService5.preDestroy [@PreDestroy]");
}
/**
* 使用@PreDestroy
*/
@PreDestroy
public void preDestroy1(){
System.out.println("DemoService5.preDestroy1 [@PreDestroy]");
}
2.2 @Bean init-method
在早期的Spring的版本使用xml实现,如
@Bean(destroyMethod = "destroyMethod")
public DemoService5 DemoService5(){
return new DemoService5();
}
对于这种实现方式,我们会发现需要额外的@Configuration来声明一个@Bean。
如果对于使用@Service、@Controller等这样的方式注入Bean的,那么这种实现方案,就有点爱莫能助了。
destroyMethod就是原来spring配置文件里bean标签上的destroy-method,这个方法需要在DemoService5类中进行定义:
/**
* 使用@Bean(destroyMethod = "destroyMethod")
*/
public void destroyMethod(){
System.out.println("DemoService5.destroyMethod [destroyMethod]");
}
2.3实现DisposableBean接口
DisposableBean是springframework下的一个类,和Spring框架算是深度捆绑了,但这一点根本不重要。对于使用很简单,就是实现接口DisposableBean:
package com.kfit.demo.service;
import org.springframework.beans.factory.DisposableBean;
import javax.annotation.PreDestroy;
/**
* 测试销毁.
*
* @author 悟纤「公众号SpringBoot」
* @date 2022-08-08
* @slogan 大道至简 悟在天成
*/
public class DemoService5 implements DisposableBean {
/**
* 使用implements DisposableBean
* @throws Exception
*/
@Override
public void destroy() {
System.out.println("DemoService5.destroy [DisposableBean]");
}
}
说明:对于类DemoService5可以使用@Service、@Component注入bean。
- 我就是我,是颜色不一样的烟火。
- 我就是我,是与众不同的小苹果。
à悟空学院:https://t.cn/Rg3fKJD
学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!
SpringBoot视频:http://t.cn/A6ZagYTi
SpringBoot交流平台:https://t.cn/R3QDhU0
SpringSecurity5.0视频:http://t.cn/A6ZadMBe
ShardingJDBC分库分表:http://t.cn/A6ZarrqS
分布式事务解决方案:http://t.cn/A6ZaBnIr
JVM内存模型调优实战:http://t.cn/A6wWMVqG
Spring入门到精通:https://t.cn/A6bFcDh4
大话设计模式之爱你:https://dwz.cn/wqO0MAy7