我们在使用@Bean往Spring的IOC容器中添加一个Bean实例的时候可以指定该实例的生命周期,就想我们刚刚开始使用xml文件配置一个Bean标签指定init-method和destroy-method一样
事例代码
public class Car {
public Car() {
System.out.println("car constructor...");
}
public void init() {
System.out.println("car init...");
}
public void destroy() {
System.out.println("car destroy...");
}
}
将Bean通过配置文件注册到Spring的IOC容器中去,并指定初始化和销毁方法
@Configuration
public class SpringConfig8 {
@Bean(name = "car", initMethod = "init", destroyMethod = "destroy")
public Car getCat() {
return new Car();
}
}
创建Spring的IOC容器,获取Car的实例
@Test
public void testAnnotation8() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig8.class);
System.out.println("Spring的IOC容器创建完成!!!");
Car car = context.getBean(Car.class);
System.out.println(car);
context.close();
}
//打印信息
car constructor...
car init...
Spring的IOC容器创建完成!!!
com.booyue.tlh.annotation.bean.Car@bae7dc0
car destroy...
我们将一个Bean注册到Spring的IOC容器中时,指定其初始化和销毁方法时,scope选用默认值(scope=singleton)时:
- 在Spring的IOC容器创建的时候,系统并会调用Bean得到构造方法和初始化方法
- 在关闭Spring的IOC容器的时候,系统也会回调Bean的销毁方法
如果我们将Bean的scope改成prototype的话,我们观察打印信息就会发现:
- 在Spring的IOC容器创建的时候,系统并不会调用Bean得到构造方法和初始化方法,只有在获取Bean实例的时候,才会调用Bean的构造和初始化方法
- 在关闭Spring的IOC容器的时候,系统也不会回调Bean的销毁方法
InitializingBean和DisposableBean接口
除了指定Bean的初始化和销毁方法,还可以通过实现InitializingBean和DisposableBean来定义初始化和销毁的逻辑
实例代码
public class Cat implements InitializingBean, DisposableBean {
public Cat() {
System.out.println("Cat constructor...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Cat afterPropertiesSet...");
}
@Override
public void destroy() throws Exception {
System.out.println("Cat destroy...");
}
}
通过配置文件将我们的Cat加入到Spring的IOC容器中去
@Configuration
public class SpringConfig9 {
@Bean(name = "cat")
public Cat getCat() {
return new Cat();
}
}
接下来我们从容器中获取Bean,然后关闭Spring的IOC容器看打印信息情况
@Test
public void testAnnotation9() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig9.class);
System.out.println("Spring的IOC容器创建完成!!!");
Cat cat = context.getBean(Cat.class);
System.out.println(cat);
context.close();
}
//打印信息
Cat constructor...
Cat afterPropertiesSet...
Spring的IOC容器创建完成!!!
com.booyue.tlh.annotation.bean.Cat@bae7dc0
Cat destroy...
@PostConstruct和@PreDestroy
另外Spring也支持JSR250的@PostConstruct和@PreDestroy两个注解来完成Bean的初始化的销毁工作
Bean的初始化和销毁方法创建方式
- 通过@Bean指定init-method和destroy-method方法
- 通过实现InitializingBean和DisposableBean接口
- 通过@PostConstruct和@PreDestroy两个注解
BeanPostProcessor接口
BeanPostProcessor可以监听Spring在将一个Bean初始化的时候的前后时刻
实现BeanPostProcessor接口,写自己的逻辑
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization ---> " + beanName);//我们这里什么也没做,就一个打印输出
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization ---> " + beanName);//我们这里什么也没做,就一个打印输出
return bean;
}
}
配置文件
@Configuration//告诉Spring这里是一个配置文件
public class SpringConfig10 {
@Bean(name = "car", initMethod = "init", destroyMethod = "destroy")
public Car getCar() {
return new Car();
}
@Bean(name = "myBeanPostProcessor")
public MyBeanPostProcessor getMyBeanPostProcessor() {
return new MyBeanPostProcessor();
}
}
获取我们定义的Car的时候,我们就能看到我们在MyBeanPostProcessor 类中的逻辑得到了输出,在Car的init方法前后postProcessBeforeInitialization和postProcessAfterInitialization的逻辑得到了打印
@Test
public void testAnnotation10() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig10.class);
System.out.println("Spring的IOC容器创建完成!!!");
MyBeanPostProcessor postProcessor = context.getBean(MyBeanPostProcessor.class);
System.out.println(postProcessor);
context.close();
}
//打印输出:
car constructor...
postProcessBeforeInitialization ---> car
car init...
postProcessAfterInitialization ---> car
Spring的IOC容器创建完成!!!
com.booyue.tlh.annotation.custom.MyBeanPostProcessor@21282ed8
car destroy...
再总结Bean的生命周期
- BeanPostProcessor.postProcessBeforeInitialization
- Bean的初始化方法
- BeanPostProcessor.postProcessAfterInitialization
- Bean的销毁方法