文章目录
简述
* bean的生命周期:
* bean创建---初始化----销毁的过程
* 容器管理bean的生命周期;
* 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
*
* 构造(对象创建)
* 单实例:在容器启动的时候创建对象
* 多实例:在每次获取的时候创建对象
*
* BeanPostProcessor.postProcessBeforeInitialization
* 初始化:
* 对象创建完成,并赋值好,调用初始化方法。。。
* BeanPostProcessor.postProcessAfterInitialization
* 销毁:
* 单实例:容器关闭的时候
* 多实例:容器不会管理这个bean;容器不会调用销毁方法;
*
一个对象从被创建,到被垃圾回收,可以划分为 5 个阶段:
- 创建 / 实例化阶段: 此时会调用类的构造方法,产生一个新的对象
- 初始化阶段: 此时对象已经创建好,但还没有被正式使用,可能这里面需要做一些额外的操作(如预初始化数据库的连接池)
- 运行使用期: 此时对象已经完全初始化好,程序正常运行,对象被使用
- 销毁阶段: 此时对象准备被销毁,已不再使用,需要预先的把自身占用的资源等处理好(如关闭、释放数据库连接)
- 回收阶段: 此时对象已经完全没有被引用了,被垃圾回收器回收
在@Bean上指定init-method和destroy-method
* 1)、指定初始化和销毁方法;
* 通过@Bean指定init-method和destroy-method;
配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Config {
@Bean(initMethod = "init", destroyMethod = "destory")
public Person person(){
return new Person();
}
}
创建类,并编写初始化和销毁方法
public class Person {
Person(){
System.out.println("person...constructor...");
}
public void init(){
System.out.println("person...init...");
}
public void destory(){
System.out.println("person...destory...");
}
}
测试类
@Test
public void test01() {
// 创建ioc容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
// 关闭容器
applicationContext.close();
}
测试结果
person...constructor...
person...init...
person...destory...
使用JSR250提供的@PostConstruct和@PreDestroy注解
手动声明注册的 Bean
,可以直接声明 init-method
和 destroy-method
,但是使用模式注解的 Bean
,@Component
注解上只有一个 value
属性,没有可以让你声明 init-method
和 destroy-method
的地方了。
JSR250
规范中除了有 @Resource
这样的自动注入注解,还有负责生命周期的注解,包括 @PostConstruct 、@PreDestroy
两个注解,分别对应 init-method
和 destroy-method
。
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class Person {
Person() {
System.out.println("person...constructor...");
}
@PostConstruct
public void postConstruct() {
System.out.println("person...postConstruct...");
}
@PreDestroy
public void preDestroy() {
System.out.println("person...preDestroy...");
}
}
启动容器,输出结果
person...constructor...
person...postConstruct...
person...preDestroy...
JSR250规范与init-method共存: JSR250 规范的执行优先级高于 init / destroy。
实现InitializingBean和DisposableBean
两个接口,而且是 SpringFramework 内部预先定义好的两个关于生命周期的接口。
触发时机与上面的 init-method 、 destroy-method
以及 JSR250 规范的两个注解一样,都是在 Bean 的初始化和销毁阶段要回调的。
* 2)、通过让Bean实现InitializingBean(定义初始化逻辑),
* DisposableBean(定义销毁逻辑);
创建类,并实现InitializingBean,DisposableBean,并注入到容器。
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class Person implements InitializingBean, DisposableBean {
Person() {
System.out.println("person...constructor...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("person...afterPropertiesSet...");
}
@Override
public void destroy() throws Exception {
System.out.println("person...destroy...");
}
}
启动容器,输出结果
person...constructor...
person...afterPropertiesSet...
person...destroy...
三种生命周期并存
准备初始化IOC容器
@PostConstruct - 执行初始化方法
InitializingBean - 执行初始化方法
init-method - 执行初始化方法
IOC容器初始化完成
准备销毁IOC容器
@PreDestroy - 执行销毁方法
DisposableBean - 执行销毁方法
destroy-method - 执行销毁方法
IOC容器销毁完成
@PostConstruct
→ InitializingBean
→ init-method
原型Bean的生命周期
单实例 Bean
的生命周期是陪着 IOC
容器一起的,容器初始化,单实例 Bean
也跟着初始化;容器销毁,单实例 Bean
也跟着销毁。
原型 Bean
由于每次都是取的时候才产生一个,所以它的生命周期与 IOC
容器无关。