BeanPostProcessor:是一个接口,bean的后置处理器(实际是在bean的初始化前后执行操作)
public class MyBeanPostProcessor implements BeanPostProcessor{
/**
* bean是容器调用构造器创建的实例
* beanName是实例的id
* 在所有初始化方法之前调用
*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* bean是容器调用构造器创建的实例
* beanName是实例的id
* 在所有初始化方法之后调用
*/
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
将MyBeanPostProcessor纳入到容器中:
@Configuration
@Import(MyBeanPostProcessor.class)
public class LifeCycleConfig {
@Bean(initMethod="init0",destroyMethod="destroy0")
public Car car(){
return new Car();
}
}
这样该容器中的所有bean在初始化前后都会执行该后置处理器中的逻辑,即使未定义初始化方法这些逻辑也会执行的,由此可以猜测:BeanPostProcessor可能是面向切面的
通过查看源码,整个逻辑是这样的:
在调用构造器之后,会为对象的所有属性赋值,赋值完成后会调用初始化方法,但是在调用初始化方法时会进入一个切面,完成在初始化的前后执行BeanPostProcessor的逻辑:容器会遍历所有的BeanPostProcessor并依次执行每个后置处理器的前置方法(postProcessBeforeInitialization),直至全部执行完或者其中一个该类方法返回null,然后完成Bean的初始化,初始化完成后,容器会继续遍历执行所有的BeanPostProcessor的后置方法(postProcessAfterInitialization),直至全部执行完或者其中一个该方法返回null
JDK1.8之后interface也可以有方法体了,子类也可以不实现接口中已有方法体的方法:
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在Spring底层的使用:
①组件通过实现ApplicationContextAware接口获取IOC容器,其实是ApplicationContextAwareProcessor在起作用
@Component
public class ContextBean implements ApplicationContextAware {
private ApplicationContext context;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
}
怎么获取到的IOC容器呢?容器在调用Bean的构造器并给所有属性赋值之后,在执行所有初始化方法之前和之后,会执行一些BeanPostProcessor接口的子类中的逻辑,比如ApplicationContextAwareProcessor,在执行ApplicationContextAwareProcessor的postProcessBeforeInitialization()方法时,会判断Bean是否实现了ApplicationContextAware接口,然后注入相应的ApplicationContext容器给Bean使用
②对组件的属性进行校验的BeanValidationPostProcessor
③InitDestroyAnnotationBeanPostProcessor:扫描Bean中标注了@PostConstruct和@PreDestroy注解的方法并执行,这也就是为什么@PostConstruct标注的初始化方法在其他初始化方法之前执行
④AutowiredAnnotationBeanPostProcessor:为bean中标注了@Autowired注解的属性赋值,这就是为什么可以在init()方法中使用@Autowired注解的属性的原因,因为在调用init方法之前会将这些属性的值注入
⑤AsyncAnnotationBeanPostProcessor:使标注了@Async的方法异步执行