spring bean的周期的各个阶段
一个受 Spring 管理的 bean,生命周期主要阶段有
-
创建:根据 bean 的构造方法或者工厂方法来创建 bean 实例对象
-
依赖注入:根据 @Autowired,@Value 或其它一些手段,为 bean 的成员变量填充值、建立关系
-
初始化:回调各种 Aware 接口,调用对象的各种初始化方法
-
销毁:在容器关闭时,会销毁所有单例对象(即调用它们的销毁方法)
-
prototype 对象也能够销毁,不过需要容器这边主动调用
-
package com.butch.a03;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class LifeCycleBean {
public static final Logger log =
LoggerFactory.getLogger(LifeCycleBean.class);
public LifeCycleBean(){
log.debug("===============无参构造器,启动!!!===========");
}
@Autowired
public void autowird(@Value("${JAVA_HOME}") String home){
log.debug("================={JAVA_HOME}依赖注入,启动!!!============");
System.out.println("home = " + home);
}
@PostConstruct
public void init(){
log.debug("==================初始化方法,启动!!!============");
}
@PreDestroy
public void destory(){
log.debug("===============销毁方法,启动!!!=================");
}
}
package com.butch.a03;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class A03 {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(A03.class, args);
run.close();
}
}
常见的bean后置处理器(六大)
bean的初始化前后的各个阶段,会通过bean的后置处理器进行增强:
创建前后的增强
-
postProcessBeforeInstantiation
-
这里返回的对象若不为 null 会替换掉原本的 bean,并且仅会走 postProcessAfterInitialization 流程
-
-
postProcessAfterInstantiation
-
这里如果返回 false 会跳过依赖注入阶段
-
依赖注入前的增强
-
postProcessProperties
-
如 @Autowired、@Value、@Resource
-
初始化前后的增强
-
postProcessBeforeInitialization
-
这里返回的对象会替换掉原本的 bean
-
如 @PostConstruct、@ConfigurationProperties
-
-
postProcessAfterInitialization
-
这里返回的对象会替换掉原本的 bean
-
如AOP代理增强
-
销毁之前的增强
-
postProcessBeforeDestruction
-
如 @PreDestroy
-
package com.butch.a03;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;
import java.beans.PropertyDescriptor;
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger(MyBeanPostProcessor.class);
@Override
public void postProcessBeforeDestruction(Object o, String s) throws BeansException {
if (s.equals("lifeCycleBean")){
log.debug("<<<<<< postProcessBeforeDestruction 销毁之前执行, 如 @PreDestroy");
}
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("<<<<<<<<<<< postProcessBeforeInstantiation 实例化之前执行,返回的bean会替换原来的bean");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("<<<<<<<<<<<<<< postProcessAfterInstantiation 实例化之后执行,如果返回false则跳过依赖注入阶段");
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("<<<<<<<<<<<<<<<< postProcessProperties 依赖注入阶段执行,如@autowired,@resource,@vaule");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("<<<<<<<<<<<<<<<<<<< postProcessBeforeInitialization 初始化之前执行,如@postcontruion,@configurproties,并且会替换调原来的bean");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("<<<<<<<<<<<<<<<<<<<< postProcessAfterInitialization 初始化之后执行,会替换调之前的bean,如aop增强");
}
return bean;
}
}
模板方法设计模式
后置处理器的设计思路即为模板方法设计模式,提高程序的可延展性质
在容器的启动的时候,bean的加载等过程都是固定的,如bean后置处理器的加载,autowird注入已经实现,如果需要增加resource注入,就需要改变bean后置处理器加载的代码,此时需要对bean进行增强扩展,可能就要改动原流程的逻辑,但是使用模板方法设计,抽象出来一个接口,去实现不同的增强,相当于说给外界留下一个增强点,可以增加自定义的增强逻辑,如果要增加新resource注入功能,则在后在后置处理器接口
package com.butch.a03;
import java.util.ArrayList;
import java.util.List;
public class TestMethodTemplate {
public static void main(String[] args) {
MyBeanFactory myBeanFactory = new MyBeanFactory();
Object bean = myBeanFactory.getBean();
System.out.println("bean = " + bean);
//在这添加需要新增强的功能
myBeanFactory.addBeanPostProcessor(bean1 -> System.out.println("解析 @Autowired"));
myBeanFactory.addBeanPostProcessor(bean1 -> System.out.println("解析 @Resource"));
System.out.println("=============增加后处理器后的bean==========");
myBeanFactory.getBean();
}
// 模板方法 Template Method Pattern
//用这个类来模拟spring bean的处理流程
static class MyBeanFactory {
public Object getBean() {
Object bean = new Object();
System.out.println("构造 " + bean);
System.out.println("依赖注入 " + bean); // @Autowired, @Resource
//在这遍历所有的增加的后处理器功能逻辑,并执行增强
for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
beanPostProcessor.inject(bean);
}
System.out.println("初始化 " + bean);
return bean;
}
private List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor){
beanPostProcessors.add(beanPostProcessor);
}
}
//相当于抽象出来一个功能,专门为依赖注入阶段增强各种不同功能逻辑
static interface BeanPostProcessor{
public void inject(Object bean);
}
}
bean 后处理的的排序
1. 实现了 PriorityOrdered 接口的优先级最高
2. 实现了 Ordered 接口与加了 @Order 注解的平级, 按数字升序
3. 其它的排在最后
package com.butch.a03;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.Order;
import java.util.ArrayList;
import java.util.List;
public class TestProcessOrder {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
List<BeanPostProcessor> list = new ArrayList<>();
list.add(new P1());
list.add(new P2());
list.add(new P3());
list.add(new P4());
list.add(new P5());
list.sort(beanFactory.getDependencyComparator());
list.forEach(processor->{
processor.postProcessBeforeInitialization(new Object(), "");
});
}
@Order(1)
static class P1 implements BeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger(P1.class);
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.debug("postProcessBeforeInitialization @Order(1)");
return bean;
}
}
@Order(2)
static class P2 implements BeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger(P2.class);
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.debug("postProcessBeforeInitialization @Order(2)");
return bean;
}
}
static class P3 implements BeanPostProcessor, PriorityOrdered {
private static final Logger log = LoggerFactory.getLogger(P3.class);
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.debug("postProcessBeforeInitialization PriorityOrdered");
return bean;
}
@Override
public int getOrder() {
return 100;
}
}
static class P4 implements BeanPostProcessor, Ordered {
private static final Logger log = LoggerFactory.getLogger(P4.class);
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.debug("postProcessBeforeInitialization Ordered");
return bean;
}
@Override
public int getOrder() {
return 200;
}
}
static class P5 implements BeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger(P5.class);
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.debug("postProcessBeforeInitialization");
return bean;
}
}
}