Spring注解开发02--------bean的生命周期
作者:互联网
概述
什么是bean的生命周期?
bean的生命周期是指一个bean,从创建,再到初始化,最后到销毁的过程!
- 构造(对象创建):
- 单实例,默认容器启动时创建对象
- 多实例,在每次获取的时候创建对象
- 初始化:
- 对象创建完毕并赋值好,调用初始化方法。
- 销毁:
- 单实例,在容器关闭时调用销毁方法
- 多实例,创建之后容器就不会管理这个bean了,容器不会调用销毁方法。
- 我们还可以通过BeanPostProcessor来进行初始化方法前后的一些操作!
在Spring中是容器来管理bean的生命周期,但是我们可以使用一些我们自定义的方法,来使得容器进行到当前bean的生命周期时来调用我们自定义的初始化与销毁方法。
Spring实现生命周期的几种方式
- @Bean方式
- 指定init-method=""与destroy-method=""
- 通过让bean实现InitializingBean(定义初始化逻辑)与DisposableBean(定义销毁逻辑)接口
- 使用JSR250提供的两个注解:
- @PostConstruct: 在bean创建完成并且属性赋值完成,来执行初始化
- @PreDestroy: 在容器销毁bean之前通知我们清理工作
- 通过BeanPostProcessor:
- 在bean初始化前后进行一些处理工作
- postProcessBeforeInitialization:在任意初始化调用之前(包括我们指定任意初始化方法之前)
- postProcessAfterInitialization:在任意初始化方法调用之后
@Bean方式实现
概述
@Bean注解为我们提供了两个属性initMethod与destroyMethod,我们使用使用时最直接赋值方法名即可。
测试
1.编写实体类person,编写构造方法,init(初始化方法)与destory(销毁方法)
package com.xdw.pojo;
public class Person {
private Integer age;
private String name;
public void init() {
System.out.println("person init。。。");
}
public void destory() {
System.out.println("person destory。。。");
}
public Person() {
}
public Person(Integer age, String name) {
this.age = age;
this.name = name;
System.out.println("person constructor。。。");
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
2.在配置类中编写我们创建bean的方法,并使用@Bean注解,设置initMethod与destoryMethod分别指向我们刚刚创建的初始化与销毁方法。
package com.xdw.config;
import com.xdw.pojo.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MainConfigOfLifeCycle {
@Bean(initMethod = "init", destroyMethod = "destory")
public Person person() {
return new Person(12, "张三");
}
}
3.编写测试类方法
@Test
public void test01() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
// 单例模式,在容器关闭时会自动销毁bean
applicationContext.close();
}
4.运行,测试结果如下:
可以发现我们指定的初始化与销毁方法被成功调用了。
总结
该种方法实现比较简单,只需要给bean设定初始化与销毁方法,再将方法名分别赋值给@Bean的initMethod与destroyMethod属性。
方式二:通过让bean实现InitializingBean(定义初始化逻辑)与DisposableBean(定义销毁逻辑)接口
概述
该种方式,需要我们创建的bean实现InitializingBean与DisposableBean接口,分别重写afterPropertiesSet与destroy方法。
测试
1.新增一个Car类,实现InitializingBean与DisposableBean接口
package com.xdw.pojo;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class Car implements InitializingBean, DisposableBean {
public Car() {
System.out.println("car constructor......");
}
@Override
public void destroy() throws Exception {
System.out.println("Car destory ......");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("car afterPropertiesSet......");
}
}
2.在配置类中编写注入方法
@Bean
public Car car() {
return new Car();
}
3.测试方法如下:
@Test
public void test01() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
applicationContext.close();
}
4.运行,测试结果如下:
我们重写的afterPropertiesSet与destroy方法被成功调用。
总结
该种方式需要我们创建的bean实现InitializingBean与DisposableBean接口,并分别重写afterPropertiesSet与destroy方法。
方式三:JSR250提供的两个注解,@PostConstruct`与`@PreDestroy
概述
这位两个注解是java提供的注解,Spring也支持。
测试
1.新增一个Dog类,编写构造方法,初始化方法,与销毁方法
package com.xdw.pojo;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class Dog {
public Dog() {
System.out.println("dog constructor 。。。。。。");
}
@PostConstruct
public void init() {
System.out.println("dog @PostConstruct 。。。。。。");
}
@PreDestroy
public void destory() {
System.out.println("dog @PreDestroy 。。。。。。");
}
}
2.在配置类中编写bean创建方法
@Bean
public Dog dog() {
return new Dog();
}
3.编写测试类
import com.xdw.config.MainConfigOfLifeCycle;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestLifeCycle {
@Test
public void test01() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
applicationContext.close();
}
}
4.运行结果,测试
可以发现,我们使用的@PostConstruct
与@PreDestroy
修饰的方法成功执行。
总结
@PostConstruct
与@PreDestroy
这两个注解是java提供的注解@PostConstruct
表示在构造方法之后执行@PreDestroy
表示在实例销毁之前执行
方式四:BeanPostProcessor bean后置处理器
概述
- BeanPostProcessor可以在bean初始化前后进行一些操作,不会在销毁bean时进行操作。
- postProcessBeforeInitialization:在任意初始化调用之前(包括我们指定任意初始化方法)
- postProcessAfterInitialization:在任意初始化方法调用之后(包括我们指定任意初始化方法)
测试
1.新增MyBeanPostProcessor类实现BeanPostProcessor接口
package com.xdw.pojo;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
// 任意初始化方法调用之前
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization >=" + beanName + ">=" + bean);
return bean;
}
// 任意初始化方法调用之后
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization >=" + beanName + ">=" + bean);
return bean;
}
}
2.在配置类上添加@ComponentScan
注解,使得我们新建的MyBeanPostProcessor
注解生效
package com.xdw.config;
import com.xdw.pojo.Dog;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.xdw.beanPostProcessor")
public class MainConfigOfLifeCycle {
@Bean
public Dog dog() {
return new Dog();
}
}
3.测试方法入下:
@Test
public void test01() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
applicationContext.close();
}
4.运行测试
我们发现postProcessBeforeInitialization方法与postProcessAfterInitialization分别在初始化方法执行前后被调用。
BeanPostProcessor执行原理
BeanPostProcessor执行原理:
populateBean(beanName, mbd, instanceWrapper); // 给bean进行赋值
initializeBean(beanName, exposedObject, mbd) {
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd); // 执行初始化
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
applyBeanPostProcessorsBeforeInitialization源码如下:
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
applyBeanPostProcessorsBeforeInitialization方法会遍历得到容器中所有的BeanPostProcessor;挨个执行BeforeInitialization,一旦返回null,跳出for循环,不会执行后面的BeanPostProcessor
总结
- 在bean初始化方法前后进行一些操作,包括我们自定义的一些初始化方法
- Spring底层使用了大量的BeanPostProcessor,bean赋值、注入其他组件、@Autowried、生命周期功能注解、@Async等都是通过BeanPostProcessor实现的
标签:02,--------,初始化,Spring,BeanPostProcessor,bean,import,方法,public 来源: https://www.cnblogs.com/xshangao/p/15855125.html