BeanPostProcessor
接口恰好由两个回调方法组成,其作用是在 调用 初始化方法之前 和调用初始化方法之后调用,那能帮我们做什么呢?
可以参考一下其实现类ApplicationContextAwareProcessor
该实现类就说是帮我们回调一些方法,通过我们的目标类判断是否是实现类了某些特定的接口,如果是则会调用对应的实现方法,进行一些依赖注入
postProcessBeforeInitialization
对象已经创建了,还未调用生命周期初始化方法@PostConstruct
,在调用这个方法之前会先执行 postProcessBeforeInitialization
问题:为什么要在初始化方法前调用呢?相当于是 目标对象创建完成后对其进行一些初始化操作,例如我们让目标对象
初始化一些
问题:为什么 依赖注入& 属性注入不在 postProcessAfterInitialization 进行处理?可以参考 spring-bean生命周期概念
postProcessAfterInitialization
对象已经创建了,已经调用生命周期初始化方法@PostConstruct
,
问题:为什么要在初始化方法后调用呢?这里我们可以对其进行一个定制,例如返回一个代理对象,为啥在这里返回代理对象呢,因为当走完这一行后基本上这个Bean 已经走完完整的 spring 生命周期~
源码分析
- refresh() 刷新容器
- finishBeanFactoryInitialization(beanFactory); 初始化所有的单实例Bean
- beanFactory.preInstantiateSingletons(); 初始化所有的单实例Bean
- getBean(beanName);获取这个Bean
- doGetBean() 获取Bean
- getSingleton() 获取Bean
- createBean() 创建Bean
- doCreateBean() 创建Bean
- initializeBean() 初始化Bean
@ComponentScan
public class BeanPostProcessorContext {
public static void main(String[] args) {
AnnotationConfigApplicationContext ax = new AnnotationConfigApplicationContext();
ax.register(BeanPostProcessorContext.class);
addInstantiationAwareBeanPostProcessor(ax);
ax.refresh();
User bean = ax.getBean(User.class);
System.out.println(bean);
}
private static void addInstantiationAwareBeanPostProcessor(AnnotationConfigApplicationContext ax) {
ConfigurableListableBeanFactory beanFactory = ax.getBeanFactory();
beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化方法前调用");
// 属性填充,
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化方法后调用");
//生产代理对象
return bean;
}
});
}
}
@Component
@Data
@ToString
class User {
private String name;
@PostConstruct
public void init(){
System.out.println("初始化方法");
}
}
后言
也就是说当直接实现了 BeanPostProcessor 方法 或者间接实现了 BeanPostProcessor 都会执行到进行一次调用,如果没有则会默认调用 接口方法 (java1.8) ,而调用时机则会是在初始化方法调用 前后进行调用的