1.生命周期四个阶段
一个受 Spring 管理的 bean,生命周期主要阶段有
-
创建:根据 bean 的构造方法或者工厂方法来创建 bean 实例对象
-
依赖注入:根据 @Autowired,@Value 或其它一些手段,为 bean 的成员变量填充值、建立关系
-
初始化:回调各种 Aware 接口,调用对象的各种初始化方法
-
销毁:在容器关闭时,会销毁所有单例对象(即调用它们的销毁方法)
-
prototype 对象也能够销毁,不过需要容器这边主动调用
-
@Component
public class LifeCycleBean {
private static final Logger log = LoggerFactory.getLogger(LifeCycleBean.class);
public LifeCycleBean() {
log.debug("构造");
}
@Autowired
public void autowire(@Value("${JAVA_HOME}") String home) {
log.debug("依赖注入: {}", home);
}
@PostConstruct
public void init() {
log.debug("初始化");
}
@PreDestroy
public void destroy() {
log.debug("销毁");
}
}
2. BeanPostProcessor的作用
一些资料会提到,生命周期中还有一类 bean 后处理器:BeanPostProcessor,会在 bean 的初始化的前后,提供一些扩展逻辑。但这种说法是不完整的
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger(MyBeanPostProcessor.class);
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 销毁之前执行, 如 @PreDestroy");
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 实例化之前执行, 这里返回的对象会替换掉原本的 bean");
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<< 实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段");
// return false;
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 依赖注入阶段执行, 如 @Autowired、@Value、@Resource");
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强");
return bean;
}
}
输出
可见不局限在会在 bean 的初始化的前后实例化前后,依赖注入和销毁前也可以。
创建前后的增强
postProcessBeforeInstantiation
这里返回的对象若不为 null 会替换掉原本的 bean,并且仅会走 postProcessAfterInitialization 流程
postProcessAfterInstantiation
这里如果返回 false 会跳过依赖注入阶段
依赖注入前的增强
postProcessProperties
如 @Autowired、@Value、@Resource
初始化前后的增强
postProcessBeforeInitialization
这里返回的对象会替换掉原本的 bean
如 @PostConstruct、@ConfigurationProperties
postProcessAfterInitialization
这里返回的对象会替换掉原本的 bean
如代理增强
销毁之前的增强
postProcessBeforeDestruction
如 @PreDestroy
3. 模版方法
public class TestMethodTemplate {
public static void main(String[] args) {
MyBeanFactory beanFactory=new MyBeanFactory();
beanFactory.getBean();
}
// 模板方法 Template Method Pattern
static class MyBeanFactory {
public Object getBean() {
Object bean = new Object();
System.out.println("构造 " + bean);
System.out.println("依赖注入 " + bean); // @Autowired, @Resource
System.out.println("初始化 " + bean);
return bean;
}
}
}
这么写不易扩展
public class TestMethodTemplate {
public static void main(String[] args) {
MyBeanFactory beanFactory=new MyBeanFactory();
beanFactory.getBean();
}
// 模板方法 Template Method Pattern
static class MyBeanFactory {
public Object getBean() {
Object bean = new Object();
System.out.println("构造 " + bean);
System.out.println("依赖注入 " + bean); // @Autowired, @Resource
System.out.println("初始化 " + bean);
return bean;
}
}
static interface BeanPostProcessor {
public void inject(Object bean); // 对依赖注入阶段的扩展
}
}
将不变的放主干,变化的抽象为接口
public class TestMethodTemplate {
public static void main(String[] args) {
MyBeanFactory beanFactory = new MyBeanFactory();
beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Autowired"));
beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Resource"));
beanFactory.getBean();
}
// 模板方法 Template Method Pattern
static class MyBeanFactory {
public Object getBean() {
Object bean = new Object();
System.out.println("构造 " + bean);
System.out.println("依赖注入 " + bean); // @Autowired, @Resource
for (BeanPostProcessor processor : processors) {
processor.inject(bean);
}
System.out.println("初始化 " + bean);
return bean;
}
private List<BeanPostProcessor> processors = new ArrayList<>();
public void addBeanPostProcessor(BeanPostProcessor processor) {
processors.add(processor);
}
}
static interface BeanPostProcessor {
public void inject(Object bean); // 对依赖注入阶段的扩展
}
}
完全体代码,此时代码就很灵活
beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Autowired"));
beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Resource"));
这些扩展功能就不用改getBean方法。