Spring的后处理器的作用是什么?能干什么?有多强大?读完就了解了。可以这么说吧,Spring中Bean的初始化基本就是围着后处理器来完成的功能强化,比如AOP也就借助于后处理器完成的。
- BeanPostProcessor
- BeanFactoryPostProcessor
- BeanDefinitionRegistryPostProcessor继承BeanFactoryPostProcessor
- InstantiationAwareBeanPostProcessor继承BeanPostProcessor
- BeanPostProcessor顾名思义就是Bean的后置处理器,主要在Bean初始化之前对Bean就行一些操作
- BeanFactoryPostProcessor是BeanFactory的后置处理器,在工厂加载完BD(BeanDefinition)后,Bean初始化前,工厂就处于一个相对稳定的状态,这个扩展点可以对BeanFactory进行操作
- BeanDefinitionRegistryPostProcessor继承与BeanFactoryPostProcessor,因为BeanFactory可以管理Bean的注册信息,因此这个类是为了能够去修改BD的定义
- InstantiationAwareBeanPostProcessor继承BeanPostProcessor,是在Bean实例化之前工作,比如AOP就是在这个后处理器进行的
能对BeanFactory进行建设的两个接口
- ImportBeanDefinitionRegistrar
- BeanFactoryPostProcessor
- ImportBeanDefinitionRegistrar:主要是可以动态的对BD进行修改和制定,动态的参与工厂的建设
- BeanFactoryPostProcessor:可以获取BeanFactory的属性,可以在BeanFactory的基础上进行操作
它们的主要区别是,BeanFactory不能对BD进行动态修改,它是BD加载完成的时候才能使用的
使用方法基本都相同,下面就列举出一种,下例就可以实现对已加载的BeanDefinition进行修改,实现偷梁换柱。
package test;
/*
* @Author Wrial
* @Date Created in 22:47 2019/12/2
* @Description
*/
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("自定义BeanFactoryPostProcessor");
GenericBeanDefinition app = (GenericBeanDefinition)beanFactory.getBeanDefinition("app");
System.out.println("当前spring容器的bean"+app.getBeanClassName());
app.setBeanClass(DemoDao.class);
System.out.println("偷梁换柱后当前spring容器的bean"+app.getBeanClassName());
}
}
package test;
/*
* @Author Wrial
* @Date Created in 14:59 2019/12/2
* @Description
*/
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AnnotationTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext=
new AnnotationConfigApplicationContext(AppConfig.class);
System.out.println(applicationContext.getBean(AppConfig.class));
}
}