三种方式
- 在指定方法上加@PostConstruct或@PreDestroy注解去指定该方法是在当前类初始化后还是销毁前执行
- 实现InitializingBean接口重写afterPropertiesSet方法去执行初始化后调用方法,或实现DisposableBean接口重写destroy方法去执行销毁前调用方法
- 在调用bean的方法上加注解@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
代码演示
@Component
public class User implements InitializingBean {
public User() {
System.out.println("This is constructor method.");
}
public void sayHello() {
System.out.println("Hello, I'm Lucifer.");
};
@PostConstruct
public void initMethod() {
System.out.println("This is init method triggered by @PostConstruct annotation.");
}
@PreDestroy
public void destroyMethod() {
System.out.println("This is destroy method triggered by @PreDestroy annotation.");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("This is init method triggered by afterPropertiesSet");
}
// implements DisposableBean interface
/*@Override
public void destroy() throws Exception {
System.out.println("This is init method triggered by DisposableBean interface");
}*/
}
@Controller
public class HelloController {
@Autowired
User user;
@RequestMapping("/hello")
public @ResponseBody String hello(@RequestParam String name) {
this.test();
return "hello, " + name;
}
@Bean(initMethod = "init", destroyMethod = "destroy")
private void test() {
user.sayHello();
}
}
项目启动后打印日志:
This is constructor method.
This is init method triggered by @PostConstruct annotation.
This is init method triggered by afterPropertiesSet
Hello, I'm Lucifer.
通过http://localhost:8081/hello?name=SpringBoot访问API后打印日志:
Hello, I'm Lucifer.
三种初始化方法执行顺序
Constructor > @PostConstruct > InitializingBean > initMethod
@PostConstruct注解的方法在BeanPostProcessor前置处理器中执行,BeanPostProcessor接口是一个回调作用,Spring容器中每个托管Bean在调用初始化方法之前,都会获得BeanPostProcessor接口实现类的一个回调。而在BeanPostProcessor回调方法中就有一段逻辑判断当前被回调bean的方法中有没有方法被initAnnotationType / destroyAnnotationType注释(即被@PostConstruct / @PreDestroy注解),如果有则添加到 init / destroy 队列中,后续一一执行。
所以@PostConstruct注解的方法先于 InitializingBean 和 initMethod 执行。
实例化bean的过程
- 通过构造器newInstance()方法创建bean实例,并对bean实例进行包装
- 将bean实例放入三级缓存
- 为bean注入属性,如果有依赖其他bean,此时会创建B的实例
- 调用相关aware方法: 如果Bean实现了BeanNameAware接口,执行setBeanName()方法;如果Bean实现了BeanFactoryAware接口,执行setBeanFactory()方法
- 调用BeanPostProcessor.postProcessBeforeInitialization()方法,@PostConstruct注解的方法就在这里执行
- 调用初始化方法,如果Bean实现了InitializingBean接口,调用Bean中的afterPropertiesSet()方法
- 调用自定义initMethod方法,@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod"),私有方法依然可以强制访问执行
- 调用BeanPostProcessor.postProcessAfterInitialization()方法,AOP在此实现
- 如果改Bean是单例,则当容器销毁且实现了DisposableBean接口,则调用destroy()方法;如果Bean是prototype,则将准备好的Bean交给调用者,后续不再管理该Bean的生命周期
Spring Bean 初始化与销毁的三种方式详解
4528

被折叠的 条评论
为什么被折叠?



