关于BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcesso两人的关系声明—— 由下图可以看出BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,属父子关系
还可以查看下族谱(类继承关系)
步骤:
-
打开想要查看的类
-
空白处右键
-
注意⚠️右键的焦点要落在类的大括号里面(不然只会出现查看依赖的选项)
-
-
Diagrams->Show Diagram
-
显示结果
嘿嘿⊂((・⊥・))⊃实属父(BeanFactoryPostProcessor)子(BeanDefinitionRegistryPostProcessor)关系,鉴定完毕!
保姆级正文开始 1. 新建类新建两个类,分别实现BeanFactoryPostProcessor接口和BeanDefinitionRegistryPostProcessor接口(任选一个也可以,本文为了介绍全面,两个同时举例)
MyBeanFactoryPostProcessor.java(实现BeanFactoryPostProcessor接口)
package com.aqin.custom.postprocessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("俺这是MyBeanFactoryPostProcessor.postProcessBeanFactory()W(`0`)W~");
}
}
MyBeanDefinitionRegistryPostProcessor.java(实现BeanDefinitionRegistryPostProcessor接口)
package com.aqin.custom.postprocessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("俺这是MyRegistryPostProcessor.postProcessBeanFactory()( ´▽`)~");
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("俺这是MyRegistryPostProcessor.postProcessBeanDefinitionRegistry()(*≧ω≦)~");
}
}
2. 让Spring识别
方式主要有2种:
方式一:在配置文件中添加定义(让spring自动识别)启动类:AqinApplication.java
package com.aqin;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Arrays;
public class AqinApplication {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml");
System.out.println(Arrays.toString(context.getBeanDefinitionNames()));
}
}
配置文件:applicationContext2.xml
测试查看输出结果:
方式二:重写customizeBeanFactory函数(用户手动添加)新建ClassPathXmlApplicationContext的继承类
MyApplicationContext.java
package com.aqin.custom.postprocessor;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyApplicationContext extends ClassPathXmlApplicationContext {
public MyApplicationContext(String... s) {
super(s);
}
}
修改启动类
package com.aqin;
import com.aqin.custom.postprocessor.MyApplicationContext;
import org.springframework.context.ApplicationContext;
import java.util.Arrays;
public class AqinApplication {
public static void main(String[] args) {
ApplicationContext context = new MyApplicationContext("applicationContext2.xml");
System.out.println(Arrays.toString(context.getBeanDefinitionNames()));
}
}
重写customizeBeanFactory函数
package com.aqin.custom.postprocessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyApplicationContext extends ClassPathXmlApplicationContext {
public MyApplicationContext(String... s) {
super(s);
}
@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
super.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
super.addBeanFactoryPostProcessor(new MyBeanDefinitionRegistryPostProcessor());
}
}
测试查看输出结果:
BBBBBBBBut、这两种方法有一点区别来吧~总结下,不知道有没有同学注意到,我在启动类里都有一行输出
System.out.println(Arrays.toString(context.getBeanDefinitionNames()));
其实就是spring上下文中的一个集合对象BeanDefinitionNames的输出,先啰嗦解释下BeanDefinitionNames这个集合(了解的同学可以直接跳过下面这段,或者瞅瞅哪里解释的不对评论区戳我~~)
spring在读取Bean后,会先将其转化成BeanDefinition(Bean定义),存入到BeanDefinitionMap和BeanDefinitionNames这两个集合中:
-
其中BeanDefinitionMap是一个Map
,key值存放字符串格式的BeanName(Bean的名称),value值存放BeanDefinition格式的Bean定义 -
BeanDefinitionNames是一个List
,里面只存放了这些Bean的名称
拿DefaultListableBeanFactory举个例子,如下图,这两个集合在类DefaultListableBeanFactory中的定义:
然后我们分别查看两种方式的输出->
虽然两种让spring发现方式新建类中的输出都被执行了,但是可以看到通过重写customizeBeanFactory函数进行扩展的spring上下文对象中的BeanDefinitionNames和BeanDefinitionMap都是空的,而通过配置文件让spring识别的则将我们在第一步新建的两个PostProcesscor都加了进去。
我们在通过Debug的方式仔细看下->
方式一:
方式二:
总之~
就是后面那种我们在第一步新建的两个类虽然也都会执行,但是第二种方法是不会被当成spring的bean添加进BeanDefinitionMap和BeanDefinitionNames这两个集合中,这是两种方式的主要区别。
欢迎发现问题的同学(大佬)指教>>>让我们一起进步(=゚ω゚)ノ抱拳.gif
下一篇我们学习下我们本次新建的这些自定义PostProcessor是在哪里进行处理的(嘿嘿(*≧ω≦)没错、就是invokeBeanFactoryPostProcessors()~~~



