Spring5学习笔记03--Bean的生命周期
内容概要:
- Spring bean 生命周期各个阶段
- 模版方法设计模式
- Bean生命周期各个阶段,调用顺序: 构造 > 依赖注入 > 初始化 > 销毁
/**
* 用于展示Bean生命周期各个阶段
* 调用顺序: 构造 > 依赖注入 > 初始化 > 销毁
*/
@Slf4j
@Component
public class LifeCycleBean {
public LifeCycleBean() {
log.debug("构造 Construct");
}
@Autowired
public void autowird(@Value("${JAVA_HOME}") String home) {
log.debug("依赖注入 @Autowired : {}", home);
}
@PostConstruct
public void init() {
log.debug("初始化 @PostConstruct");
}
@PreDestroy
public void destroy() {
log.debug("销毁 @PreDestroy");
}
}
- 测试类
@SpringBootApplication
public class S03Application {
public static void main(String[] args) {
// 启动程序,返回Spring容器
ConfigurableApplicationContext context = SpringApplication.run(S03Application.class, args);
// 关闭容器
context.close();
}
}
- 输出
构造 Construct
依赖注入 @Autowired : xxx/jdk1.8.0_261.jdk/Contents/Home/
初始化 @PostConstruct
销毁 @PreDestroy
- 验证bean后处理器进行功能增强的时机
- 自定义 MyBeanPostProcessor 实现
InstantiationAwareBeanPostProcessor
和DestructionAwareBeanPostProcessor
- 自定义 MyBeanPostProcessor 实现
/**
* bean后处理器进行功能增强的时机
*/
@Slf4j
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<<<< 实例化(构造)之前执行,如果返回的对象不为null,会替换掉原本的bean;返回null,保持原有不变");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<<<< 实例化(构造)之后执行,如果返回false,会跳过依赖注入阶段;返回true,不跳过");
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<<<< 依赖注入阶段执行,一些Bean后处理器会在这里执行一些扩展功能,如 @Autowired @Value @Resource");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<<<< 初始化之前执行,返回的对象会替换调原本的bean, 如 @PostConstruct @ConfigurationProperties"); //@PostConstruct 虽然是Post 但是在初始化完成前执行
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<<<< 初始化之后执行,返回的对象会替换调原本的bean, 如代理增强");
}
return bean;
}
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<<<< 销毁之前执行, 如 @PreDestroy");
}
}
}
模版方法:静动结合
-
静-固定不变的步骤
-
动-需要回调的接口,不确定的逻辑抽象成接口
-
Bean后处理器采用的是模版方法设计模式来进行功能增强设计
- 固定不变的形成主干,后续需要扩展的,抽象成接口
- 这样后续加各种扩展功能,不需要对getBean()方法进行改动
使用模版方法自定义一个Bean后处理器
- 主干逻辑
// 定义BeanFactory
public class MyBeanFactory {
// getBean01() 方法每次添加功能都需要重写修改方法,不支持功能扩展
public Object getBean01() {
Object bean = new Object();
System.out.println("构造 " + bean);
System.out.println("依赖注入 " + bean);
System.out.println("初始化 " + bean);
return bean;
}
}
-
想要在Bean初始化之前添加一些功能,进行功能扩展
-
getBean01() 方法每次添加功能都需要重写修改方法
-
将固定不变的部分形成主干逻辑
-
在需要进行功能增加的地方,需要扩展的部分抽象为接口
-
-
接口抽象
public interface BeanPostProcessor {
// 对依赖注入阶段的扩展
public void inject(Object bean);
}
- 在需要进行功能增加的地方,调用接口进行扩展,同时对外提供添加功能扩展接口的入口
public class MyBeanFactory {
// 定义Bean 后处理器的列表
List<BeanPostProcessor> processors = new ArrayList<>();
public Object getBean02() {
Object bean = new Object();
System.out.println("构造 " + bean);
System.out.println("依赖注入 " + bean);
// 依赖注入阶段的扩展
for(BeanPostProcessor process : processors) {
process.inject(bean);
}
System.out.println("初始化 " + bean);
return bean;
}
// 对外提供添加Bean 后处理器的入口
public void addBeanPostProcessor(BeanPostProcessor processor) {
processors.add(processor);
}
}