这里要介绍的是Spring的扩展类点之一的:BeanPostProcessor. 废话不多说,开搞!
1.准备代码

- TestProcessor类
@Component
public class TestProcessor implements BeanPostProcessor ,PriorityOrdered{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("personService")){
System.out.println("BeforeInitialization1");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("personService")){
System.out.println("AfterInitialization1");
}
return bean;
}
@Override
public int getOrder() {
return 200;
}
}
- TestProcessor2类
@Component
public class TestProcessor2 implements BeanPostProcessor,PriorityOrdered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("personService")){
System.out.println("BeforeInitialization2");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("personService")){
System.out.println("AfterInitialization2");
}
return bean;
}
@Override
public int getOrder() {
return 199;
}
}
- PersonService类
@Component
public class PersonService {
public PersonService() {
System.out.println("personService构造方法执行了");
}
@PostConstruct
public void init(){
System.out.println("init方法执行了");
}
}
- PersonService2类
@Component
public class PersonService2 implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("全局对象:"+ applicationContext);
}
}
- SpringConfiguration类
@ComponentScan("com.v1")
public class SpringConfiguration {
}
- Test01类
public class Test01 {
public static void main(String[] args) {
//这个构造方法会把Spring所有的环境都准备好
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
}
}
2.点击 `AnnotationConfigApplicationContext`
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//这个类有父类,所以会先初始化父类的构造方法,接着初始化自己的构造方法
//调用无参构造方法进行初始化一个读取器和扫描仪
this();
//把配置类加载进 DefaultListableBeanFactory 的map集合中
//配置类可以一次性传多个,这个方法执行后,只是把配置类加载进了 DefaultListAbleBeanFactory的map集合中
//还没有扫描其他的的加了组件的类
register(annotatedClasses);
//实例化所有被加了组件的对象
refresh();
}
3.点击 ` refresh()` 方法
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
//这个方法不是重点,可以暂时认为他不干任何事情
prepareRefresh();
//获取工厂对象 ,本质是DefaultListableBeanFactory对象
//其实读取xml文件变成beanDefinition,也是在这里面完成的
//所以这里面的功能和register(annotatedClasses);功能很像
//一个是是从xml文件中读取配置信息,一个是通过类的注解读取信息
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//为BeanFactory配置类加载器、后置处理器等等
//这个方法比较重要
prepareBeanFactory(beanFactory);
//剩余的代码省略.....
}
4.点击 `prepareBeanFactory` 方法
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//添加一个类加载器
beanFactory.setBeanClassLoader(getClassLoader());
//bean的表达式解析,以后再讲,在前台页面可以获取到bean表达式的一些属性
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//对象与string类型的转换 <property >
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//重要方法
//为Spring添加后置处理器 ApplicationContextAwareProcessor 实现了BeanProcessor接口
//我们主要查看 重写接口的 postProcessBeforeInitialization ()方法
//主要作用:判断当前bean对象实现了里面的那些接口,从而在bean类获取对应的对象
//一般我们会实现 ApplicationContextAware 接口获取 applicationContext
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//以下是添加自动注入忽略的列表,不是重点
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
//等讲到bean的实例化的过程时,会说明
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//这个ApplicationListenerDetector作用: 某个类实现了ApplicationListener接口,可以获取到一个ApplicationEvent对象
//ApplicationEvent对象存储有reader,scanner,registry,beanFactory等对象
//注意实现ApplicationListener的前提是,这个bean必须是单例的
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//剩余的代码省略.....
}
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
解析这个方法之前,我们看一下 BeanFactory
工厂里面到底存放了哪些数据

粉色部分就是 BeanFactory
的示意图
- 绿色部分: Spring初始化的时候,所有的
beanDefinition
都存储在这个beanDefinitionMap
集合中 - 黄色部分:
beanDefinitionNames
集合存储所有beanDefinition
的名称 - 深紫部分:
beanPostProcessors
集合存储着所有的后置处理器,也就是实现了BeanPostProcessor
接口的类 - 浅绿部分:
getBeanNamesForType
,beanFactory
中的一个方法,通过类型得到一个beanName - 浅紫部分:
singletonObjects
,实例化后的类会存储在这个集合中
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this))
这个方法把 ApplicationContextAwareProcessor
添加进了 beanPostProcessors
,说明这个类是一个实现了
BeanPostProcessors
的后置处理器
5.点击 `ApplicationContextAwareProcessor` `
查看 ApplicationContextAwareProcessor
,果然它实现了 BeanPostProcessor
6.点击 `BeanPostProcessor`
public interface BeanPostProcessor {
/*
* 在bean的初始化之前执行
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/*
* 在bean的初始化之后执行
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
BeanPostProcessor
是Spring框架提供的一个扩展类点之一- 扩展类点其实有很多种的 例如实现
BeanFactoryPostProcessor
接口也是 BeanPostProcessor
作用:- 通过实现
BeanPostProcessor
接口,程序员就可以插手bean的实例化过程,从而减轻beanFactory的负担 - 这个接口可以被多个类实现,会形成一个列表, 通过实现
PriorityOrdered
可以改变实现类的执行顺序,getOrder返回值越小越优先执行 - AOP的就是在bean实例化后期将切面逻辑织入bean实例中的
- AOP也是通过
BeanPostProcessor
和IOC容器建立起了联系
- 通过实现
Spring默认提供很多BeanPostProcessor的实现类
其实这个接口的本身方法特别的简单,简单到令人发指,但是他的实现类巨多,实现类的方法内的逻辑复杂的程 度也令人发指
前面我们准备了两个处理器 TestProcessor
,TestProcessor2
都实现了 BeanPostProcessor
和 PriorityOrdered
- TestProcessor类
@Component
public class TestProcessor implements BeanPostProcessor ,PriorityOrdered{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//所有的类的实例化过程中都会执行执行实现了BeanPostProcessor后置处理器
//为了避免其他类做实例化的时候,也打印BeforeInitialization1,影响测试
if (beanName.equals("personService")){
System.out.println("BeforeInitialization1");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("personService")){
System.out.println("AfterInitialization1");
}
return bean;
}
@Override
public int getOrder() {
return 200;
}
}
- TestProcessor2类
@Component
public class TestProcessor2 implements BeanPostProcessor,PriorityOrdered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("personService")){
System.out.println("BeforeInitialization2");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("personService")){
System.out.println("AfterInitialization2");
}
return bean;
}
@Override
public int getOrder() {
return 199;
}
}
两个后置处理器都实现了 BeanPostProcessor
的init和after方法,实现了 PriorityOrdered
的 getOrder
方法
实现 getOrder
的后置处理器,返回值为 int 类型,返回值越小,执行的顺序越靠前
我们回到 Test01
运行测试类
测试结果:
personService构造方法执行了
BeforeInitialization2
BeforeInitialization1
init方法执行了
AfterInitialization2
AfterInitialization1
全局对象:org.springframework.context.annotation.AnnotationConfigApplicationContext@100955a, started on Sun Dec 08 11:48:03 CST 2019
7.我们回到 `ApplicationContextAwareProcessor`类中
既然我们已经知道了 BeanPostProcessors
的作用,我们看看 ApplicationContextAwareProcessor
这个Spring内部的后置处理器的init方法和after方法里面到底干了哪些事
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
private final StringValueResolver embeddedValueResolver;
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}
@Override
@Nullable
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
//这个方法不会进入
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
//这个重点
invokeAwareInterfaces(bean);
}
return bean;
}
/**
* 判断当前的bean,实现了什么类型的接口,然后根据判断设置类
* @param bean
*/
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
//(1)如果bean实现了EnvironmentAware接口,可以获取环境对象
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
//(2)如果bean实现了EmbeddedValueResolverAware接口,可以获取embeddedValueResolver对象
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
//(3)如果bean实现了ResourceLoaderAware接口,可以获取applicationContext工厂对象
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
//(4)如果bean实现了ApplicationEventPublisherAware接口,可以获取applicationContext工厂对象
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
//(5)如果bean实现了MessageSourceAware接口,可以获取applicationContext工厂对象
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
//(6)如果该bean实现了ApplicationContextAware接口 ,那么就把工厂applicationContext,传进去
//在bean的类中重写ApplicationContextAware的set方法 就可以在该bean中获取到整个工厂
//这时候想获取哪个对象都可以了
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
通过查看 ApplicationContextAwareProcessor
处理器,我们发现 ,它同样是实现了 BeanPostFactory
的两个方法 postProcessBeforeInitialization
和 postProcessAfterInitialization
方法,但是 后置方法并没有干任何事,我们重点查看 前置方法
在 ApplicationContextAwareProcessor
方法中,调用 invokeAwareInterfaces
方法,
查看 invokeAwareInterfaces
方法,我们查询,只要实现某一个接口就能获取相应的对象
例如在准备代码中,我们的 PersonService2
实现了 ApplicationContextAware
接口
@Component
public class PersonService2 implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("全局对象:"+ applicationContext);
}
}
实现了 setApplicationContext
就可以获取全局对象
假设你这样一个需求,需要初始化的时候获取到Spring的全局对象,那么你就可以实现 ApplicationContextAware
总结一下 ApplicationContextAwareProcessor
到底干了哪些事?
- 实现了
BeanPostProcessors
接口 - 在
postProcessBeforeInitialization
方法里面执行invokeAwareInterfaces
方法 - 在
invokeAwareInterfaces
方法中,判断当前的Bean实现了哪些接口,如果实现了某个接口就可以获取对应的对象
8.我们回到 第四步 点击 `prepareBeanFactory` `方法
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//添加一个类加载器
beanFactory.setBeanClassLoader(getClassLoader());
//bean的表达式解析,以后再讲,在前台页面可以获取到bean表达式的一些属性
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//对象与string类型的转换 <property >
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//重要方法
//为Spring添加后置处理器 ApplicationContextAwareProcessor 实现了BeanProcessor接口
//我们主要查看 重写接口的 postProcessBeforeInitialization ()方法
//主要作用:判断当前bean对象实现了里面的那些接口,从而在bean类获取对应的对象
//一般我们会实现 ApplicationContextAware 接口获取 applicationContext
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//以下是添加自动注入忽略的列表,不是重点
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
//等讲到bean的实例化的过程时,会说明
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//这个ApplicationListenerDetector作用: 某个类实现了ApplicationListener接口,可以获取到一个ApplicationEvent对象
//ApplicationEvent对象存储有reader,scanner,registry,beanFactory等对象
//注意实现ApplicationListener的前提是,这个bean必须是单例的
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//剩余的代码省略.....
}
在该方法中 ,不仅添加了 ApplicationContextAwareProcessor
,这个后置处理器,其实还添加了 ApplicationListenerDetector
这个处理器
9.点击 `ApplicationListenerDetector`
我们主要查看 postProcessAfterInitialization
方法
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
//判断当前的bean是否实现了ApplicationListener这个接口,如果没有实现直接跳过
if (bean instanceof ApplicationListener) {
//如果有实现,则判断当前的bean实现是单例的
//singletonNames存储用户所有的bean,
// key值为 beanName ,value值为Boolean值 false 代表为不是单例 true代表为单例
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
else if (Boolean.FALSE.equals(flag)) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
//如果不是单例的,删除掉
this.singletonNames.remove(beanName);
}
}
return bean;
}
这个方法主要作用:
执行了 ApplicationListener
,必须是 单例的,才可以获取到相应的对象
Spring5源码地址:
github.com/zouchangfu/… gitee.com/zouchangfu/…
Spring5源码都是已经构建好的了,无需再使用gradle进行构建了,直接打开就可以跑起来