在 Spring - IoC 容器之 Bean 的生命周期 这篇文章中,我们了解了 Spring
中 Bean
的生命周期,我们知道底层是通过回调实现的。同时对于其他情况的回调,Spring 官方文档 中有介绍,BeanPostProcessor
接口中定义了回调方法,我们可以实现这些方法来提供自己的实例化逻辑、依赖处理逻辑等。如果我们想要在 Spring IoC 容器
完成 Bean
的 实例化
、配置
和初始化
之后实现一些自定义的逻辑,可以定义一个或多个自定义的 BeanPostProcessor
实现。
同时,如果我们配置了多个 BeanPostProcessor
实例,我们可以通过实现 Ordered
接口设置 order
属性来控制这些实例的运行顺序。
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
首先定义一个 BeanPostProcessor
的实现类:
@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;
}
}
@Component
public class Cat implements InitializingBean, DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("cat destroy...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("cat afterPropertiesSet...");
}
}
创建 IoC 容器后,输出结果:
// 配置类初始化前调用
postProcessBeforeInitialization...mainConfigOfLifeCycle:com.keke.config.MainConfigOfLifeCycle$$EnhancerBySpringCGLIB$$661f10cf@4b213651
// 配置类初始化之后调用
postProcessAfterInitialization...mainConfigOfLifeCycle:com.keke.config.MainConfigOfLifeCycle$$EnhancerBySpringCGLIB$$661f10cf@4b213651
// Bean 初始化调用之前
postProcessBeforeInitialization...com.keke.bean.Cat:com.keke.bean.Cat@4241e0f4
// Bean 初始化
cat afterPropertiesSet...
// Bean 初始化调用之后
postProcessAfterInitialization...com.keke.bean.Cat:com.keke.bean.Cat@4241e0f4
// 容器关闭,Bean 销毁
cat destroy...
上面的 org.springframework.beans.factory.config.BeanPostProcessor
接口,定义了两个默认方法,postProcessBeforeInitialization
方法在 InitializingBean.afterPropertiesSet()
或 自定义的 init 方法
等初始化方法之前执行,postProcessAfterInitialization
在之后执行。
ApplicationContext
会自动检测实现了 BeanPostProcessor
接口的实现类,并在 Bean
创建过程中调用这些 BeanPostProcessor
,当然,这些实现了 BeanPostProcessor
接口的实现类需要作为 Bean
注册到 IoC 容器
中。
在 AbstractAutowireCapableBeanFactory
的 doCreateBean
方法中执行了创建 Bean
的过程:
在核心方法 initializeBean
方法中执行了初始化 Bean
的操作:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
...
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 执行所有 BeanPostProcessor 实现类的 postProcessBeforeInitialization 方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 执行所有 BeanPostProcessor 实现类的 postProcessAfterInitialization 方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
在 Spring
底层,大量使用了 BeanPostProcessor
来进行 Bean
的初始化前后的操作,我们查看 BeanPostProcessor
的常见实现类:
InitDestroyAnnotationBeanPostProcessor
就是用来处理@PostConstruct
和@PreDestroy
注解的。AutowiredAnnotationBeanPostProcessor
是用来处理@Autowired
注解的。