本文地址https://blog.youkuaiyun.com/hancoder/article/details/111413351
说明,本文参考了子路老师博客https://blog.youkuaiyun.com/java_lyvee/category_7351027.html,但自己也看过很多这方面的视频,包括尚硅谷的注解驱动开发,所以加了些自己的说明,尽量简洁。个人认为此文是我近期写的最好的一篇了,我感觉快要打通ssm源码整合了。
按理说工厂后置处理器没有getBean重点,但是我读了那么久源码迟迟有些地方不懂,就是因为当初没有读好工厂的后置处理器,一直没有搞懂注解的注册时机,再加上尚硅谷讲的@EnableAspectJAutoProxy也没说好到底怎么个注册法,看了几遍才发现是工厂后置处理器的问题。故写了此文
正在更新spring源码系统文章:
一、工厂后置处理器基础知识
工厂后置处理器的作用是新增和修改bean定义的,而spring中有两个接口与工厂后置处理器有关,分别是BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor。
- BeanFactoryPostProcessor:需要实现一个方法。只能修改bean定义
- BeanDefinitionRegistryPostProcessor:他本身有一个需要实现方法,但因为继承了上面的BeanFactoryPostProcessor接口,所以需要实现2个方法。分别是修改和添加bean定义
在实际开发中用的比较少,但各个框架源码整合中用的比较多,这里我们就不写用法了,直接看helloworld吧。
二、测试代码
bean定义:bean Definition,我们简称bd,存放bd的map我们简写为bd map,不懂bd的可以取前文看
1 工厂后置处理器
我们首先需要了解他们的用法,如下,我分别为每个接口创建了个实现类,只做了简单打印,用来看看他当时里面有什么bean定义,并用注解@Component将他们加到spring容器中。
1.1 注解的:
这里是意思是定义BeanFactoryPostProcessor的实现类,并且在上面@Component。然后在里面的postProcessBeanFactory()方法里打印当前有多少个bd
@Component
public class MyFacPostProcess_zhujie // 后面有_zhujie的标识
implements BeanFactoryPostProcessor {
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("===注解的MyFacPostProcess.postProcessBeanFactory()被执行。。。");
int count = beanFactory.getBeanDefinitionCount();//bean定义的数量
String[] names = beanFactory.getBeanDefinitionNames();//bean定义的名字
System.out.println("当前BeanFactory中有"+count+" 个Bean");
System.out.println(Arrays.asList(names));
}
}
和上面的逻辑一样,定义BeanDefinitionRegistryPostProcessor的实现类,并@Component。他们都是后置处理器,只不过BeanDefinitionRegistryPostProcessor可以新增和修改bd,而上面的BeanFactoryPostProcessor只能修改bd。
所以我们在它的新增bd方法里尝试new bd并设置class,然后用registry注册器注册到容器中
@Component
public class MyBeanDefinitionRegistryPostProcessor_zhujie
implements BeanDefinitionRegistryPostProcessor {
@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("===注解的MyBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()执行。。。");
int count = registry.getBeanDefinitionCount();//bean定义的数量
String[] names = registry.getBeanDefinitionNames();//bean定义的名字
System.out.println("当前BeanFactory中有"+count+" 个Bean");
System.out.println(Arrays.asList(names));
// 新增bd
GenericBeanDefinition genericBeanDefinition =
new GenericBeanDefinition() ;
genericBeanDefinition.setBeanClass(Yellow.class);
registry.registerBeanDefinition("yellow1",genericBeanDefinition);
}
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("===注解的MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory()执行。。。");
int count = beanFactory.getBeanDefinitionCount();//bean定义的数量
String[] names = beanFactory.getBeanDefinitionNames();//bean定义的名字
System.out.println("当前BeanFactory中有"+count+" 个Bean");
System.out.println(Arrays.asList(names));
}
}
1.2 通过ac.addBeanFactoryPostProcessor添加的实体bean
这里的意思是我们又定义了上面两个接口的实现类,只不过没加@Component,一会再手动注册
注意不要加@Component注解,我们要手动注册工厂后置处理器。而且我们传入ac的时候已经是实例化好的
public class RuCanBeanDefinitionRegistryPostProcessor // rucan的意思是说一会要手动注册
implements BeanDefinitionRegistryPostProcessor {
@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("===入参的registry.postProcessBeanDefinitionRegistry()执行。。。");
}
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("===入参的registry.postProcessBeanDefinitionRegistry()执行。。。");
}
}
public class RuCanBeanFactoryPostProcessor
implements BeanFactoryPostProcessor {
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("===入参的普通factoryPostPro.postProcessBeanDefinitionRegistry()执行。。。");
}
}
1.3 通过ac.registerBeanDefinition添加的bd
(下面这两个类不用太在意,其实是我前期没学好弄的,但加上也无所谓,我们就能判断ac.addBeanFactoryPostProcessor和ac.registerBeanDefinition的区别了)
public class MyFacPostProcess_ShouDongZhuRu
implements BeanFactoryPostProcessor{
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("===手动注入的MyFacPostProcess.postProcessBeanFactory()被执行。。。");
int count = beanFactory.getBeanDefinitionCount();//bean定义的数量
String[] names = beanFactory.getBeanDefinitionNames();//bean定义的名字
System.out.println("当前BeanFactory中有"+count+" 个Bean");
System.out.println(Arrays.asList(names));
}
}
public class MyBeanDefinitionRegistryPostProcessor_ShouDongZhuRu
implements BeanDefinitionRegistryPostProcessor{
@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("===手动注入的MyBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()执行。。。");
int count = registry.getBeanDefinitionCount();//bean定义的数量
String[] names = registry.getBeanDefinitionNames();//bean定义的名字
System.out.println("当前BeanFactory中有"+count+" 个Bean");
System.out.println(Arrays.asList(names));
GenericBeanDefinition genericBeanDefinition =
new GenericBeanDefinition() ;
genericBeanDefinition.setBeanClass(Blue.class);
registry.registerBeanDefinition("bule1",genericBeanDefinition);
}
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("===手动注入的MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory()执行。。。");
int count = beanFactory.getBeanDefinitionCount();//bean定义的数量
String[] names = beanFactory.getBeanDefinitionNames();//bean定义的名字
System.out.println("当前BeanFactory中有"+count+" 个Bean");
System.out.println(Arrays.asList(names));
}
}
2 配置类
为了能扫描到上面的注解,我们定义配置类并扫描,此外在里面@Bean一个普通的car对象
@Configuration // 告诉Spring这是一个配置类
@ComponentScan(value="com.atguigu")
public class MainConfigFacPostProcesser {
// 简单注入一个bean,观察执行时机
@Bean
Car Car1(){
return new Car();
}
}
3 启动类的改写
我们的启动类一般的写法是new AnnotationConfigApplicationContext(Config.class)这样子,但我们看一下他源码
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
他分为了三个步骤,为了后续解释的需要,我们给他们分开写。另外我们应该意识到,在下面加注释就是在上面加注释,执行时机都是一样的。我们加了6个关键点,为了观察工厂的状态
- 比较ac.registerBeanDefinition和ac.addBeanFactoryPostProcessor方法的区别
public class MainTest1 {
public static void main(String[] args) {
// 1 去初始化工厂
// 打断点。下面这句就是创建了一个空工厂
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext

本文深入探讨Spring工厂后置处理器,介绍其基础知识,包括BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的作用。通过测试代码展示不同方式注册工厂后置处理器,观察bd map变化和执行时机。还对ConfigurationClassPostProcessor进行解读,分析AOP注解时机及整合源码的方法,最后探讨AnnotatedBeanDefinitionReader的作用和应用场景。
最低0.47元/天 解锁文章
8845

被折叠的 条评论
为什么被折叠?



