背景
初始化bean
@PostConstruct注解
需要结合@Configuration、@Service、@Component注解一起使用,如此一来会在Bean的依赖注入完成之后, 执行被 @PostConstruct 修饰的方法。注意:一个类只能有一个用 @PostConstruct 修饰的方法。
@Bean(initMethod = "initMethod")
需要结合@Configuration一起使用,用来new一个bean,并初始化bean,最后把构造好的bean,交给Spring容器。
InitializingBean接口
需要实现InitializingBean接口,并覆盖afterPropertiesSet方法,同样是在依赖注入完成之后,进行一些初始化工作,比如:属性值校验等。
销毁bean
@PreDestroy注解
在Spring容器将该bean移除时,会回调被@PreDestroy注解修饰的方法。
@Bean(destroyMethod = "destroyMethod")
需要结合@Configuration一起使用,在初始化bean的时候,声明bean销毁方法
DisposableBean接口
需要实现DisposableBean接口,并覆盖destroy()方法,在bean销毁的时候,进行一些兜底的销毁工作,比如:关闭JDBC连接、Redis连接、Es连接等操作。
实战
普通Bean TestBean
@Slf4j
public class TestBean implements DisposableBean {
private String name;
public TestBean() {
log.info("TestBean init");
}
public String getName() {
return name;
}
/**
* 初始化bean方法
*/
public void initMethod() {
name = "testBean";
}
/**
* 销毁bean方法
*/
@PreDestroy
public void destroyMethod2() {
log.info("@PreDestroy指定的前置方法: testBean destroyMethod bean销毁方法");
}
public void destroyMethod(){
log.info("@Bean指定的销毁方法:testBean destroyMethod bean销毁方法");
}
@Override
public void destroy() throws Exception {
log.info("DisposableBean接口指定的销毁方法:testBean destroy bean销毁方法");
}
}
配置类 TestConfig
@Slf4j
@Configuration
public class TestConfig implements InitializingBean {
@Autowired
private TestBean testBean;
private static String DEFAULT_SERVICE_ID = null;
private static String DEFAULT_SERVICE_NAME = null;
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
public TestBean testBean() {
return new TestBean();
}
@PostConstruct
public void init() {
log.info("@PostConstruct check autowired, testBean = {}", testBean);
DEFAULT_SERVICE_ID ="webdoor";
log.info("@PostConstruct:webdoor DEFAULT_SERVICE_ID = {}", DEFAULT_SERVICE_ID);
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("afterPropertiesSet check autowired, testBean = {}", testBean);
DEFAULT_SERVICE_NAME = testBean.getName();
log.info("@afterPropertiesSet:webdoor DEFAULT_SERVICE_NAME = {}", DEFAULT_SERVICE_NAME);
}
}
日志
2024-09-05 16:11:34.822 INFO [web-door,,,] 1069 --- [ main] com.bryant.config.bean_init.TestBean : TestBean init
2024-09-05 16:11:34.825 INFO [web-door,,,] 1069 --- [ main] com.bryant.config.bean_init.TestConfig : @PostConstruct check autowired, testBean = com.bryant.config.bean_init.TestBean@33e6bd36
2024-09-05 16:11:34.825 INFO [web-door,,,] 1069 --- [ main] com.bryant.config.bean_init.TestConfig : @PostConstruct:webdoor DEFAULT_SERVICE_ID = webdoor
2024-09-05 16:11:34.826 INFO [web-door,,,] 1069 --- [ main] com.bryant.config.bean_init.TestConfig : afterPropertiesSet check autowired, testBean = com.bryant.config.bean_init.TestBean@33e6bd36
2024-09-05 16:11:34.827 INFO [web-door,,,] 1069 --- [ main] com.bryant.config.bean_init.TestConfig : @afterPropertiesSet:webdoor DEFAULT_SERVICE_NAME = testBean
2024-09-05 16:11:53.153 INFO [web-door,,,] 1069 --- [extShutdownHook] com.bryant.config.bean_init.TestBean : @PreDestroy指定的前置方法: testBean destroyMethod bean销毁方法
2024-09-05 16:11:53.154 INFO [web-door,,,] 1069 --- [extShutdownHook] com.bryant.config.bean_init.TestBean : DisposableBean接口指定的销毁方法:testBean destroy bean销毁方法
2024-09-05 16:11:53.154 INFO [web-door,,,] 1069 --- [extShutdownHook] com.bryant.config.bean_init.TestBean : @Bean指定的销毁方法:testBean destroyMethod bean销毁方法
总结
bean的初始化方法调用位于bean的属性赋值之后,以上三种方式来指定bean的初始化方法,执行顺序如下:
bean的销毁方法调用位于bean(或容器)被销毁的时候,以上三种方式来指定bean的销毁方法的执行顺序如下: