Loading

Spring源码学习笔记5——注册BeanPostProcessor,初始化事件多播器,注册事件监听器

一丶前言

上篇Spring容器回调完所有的BeanFactoryPostPocessor,之后可以做到替换所有占位符,解析所有配置类等工作,这篇还会迎来一个Spring留给我们扩展的一个接口,涉及到Aop的实现

二丶注册BeanPostProcessor后置处理器

1.什么是BeanPostProcessor

一个允许自定义修改新 bean 实例的工厂接口,作用是在Bean对象在实例化和依赖注入完毕后,在显示调用初始化方法的前后添加我们自己的逻辑。注意是Bean实例化完毕后及依赖注入完成后触发的

和上篇的 BeanFactoryPostProcessor 名称很像,但是BeanFactoryPostProcessor是针对整个BeanFactory 进行操作,允许我们修改BeanDefinition,注册我们自己的BeanDefinition等,针对一个Bean使用BeanPostProcessor更好,可以为这个Bean生成一个代理
public interface BeanPostProcessor {
	
   // bean实例化但属性没有填充时回调
   @Nullable
   default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }
 // bean 依赖注入,属性填充后调用
   default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }

}

2.注册BeanPostProcessor

image-20220529140642877

处理流程也比较简单,获取BeanFactory中的BeanPostProcessor类型的bean,对于实现PriorityOrdered的BeanPostProcessor,排序并优先放入BeanPostProcessor集合中(通常是一个CopyOnWriteList)先放意味着会先执行,对于实现Ordered的BeanPostProcessor,排序再放入,没有实现Ordered or PriorityOrdered的BeanPostProcessor,不会排序,直接放入(注意这说明BeanPostProcessor的顺序不会受到@Order注解的影响,可能是觉得BeanPostProcessor肯定是需要编写一个类实现接口的,那么继承以下Ordered 和PriorityOrdered吧 )最后对于实现了MergedBeanDefinitionPostProcessor的BeanPostProcessor进行放入,最后把ApplicationListenerDetector放在末尾(笔记三说过这个类,主要是在监听器类型的bean被销毁的时候,会从事件多播器中移除)

3.MergedBeanDefinitionPostProcessor

image-20220529143410192

MergedBeanDefinitionPostProcessor 的调用是在创建完 bean 实例之后,在 Bean属性填充 之前,将调用 MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition 方法。

3.1 CommonAnnotationBeanPostProcessor

解析类中的@Resource,@PostConstruct,@PreDestroy,并且正确的时机执行

image-20220529144949477

image-20220529145050011

其中这个类还实现了 InstantiationAwareBeanPostProcessor,在Bean设置属性的时候,获取@Resouce注解并且进行依赖注入

3.2 AutowiredAnnotationBeanPostProcessor

解析@Autowrie,和@Value注解,在依赖注入的时候发会作用

还要很多和Bean生命周期相关的接口,贯穿bean的生命周期,这个后续Bean生命周期学习中进行总结

三丶初始化事件多播器

image-20220529150249396

1.AbstractApplicationContext推送事件

image-20220529151337021

注意当前容器执行之后还会调用父容器中的监听器响应

2.SimpleApplicationEventMulticaster

事件多播器的简单实现

2.1 推送事件

image-20220529150918512

image-20220529151043939

四丶注册事件监听器

image-20220529152344016

负责把事件监听器 注册到多播器中,并且在事件多播器初始化执行之前,可能存在一些事件没有处理,这些事件都会放在earlyApplicationEvents集合中,在多播器初始化后,会把earlyApplicationEvents置为null 以后的事件都是直接委托给多播器进行推送

1.对于@EventLister的方法是怎么注册

这种类型的方法被封装成了ApplicationLister,也是在注册事件监听器会注册到多播器中,注册到多播器,存在一个类——EventListenerMethodProcessor负责处理这些方法,在调用所有BeanFactoryPostProcessor的时候会调用到

EventListenerMethodProcessor

1.1类结构图

image-20220529154240747

  • SmartInitializingSingleton 具有方法 afterSingletonsInstantiated 在bean初始化后会被容器回调使用

1.2 初始化解析Method 生成ApplicationLister的策略

EventListenerMethodProcessor的 postProcessBeanFactory方法

image-20220529154648804

public interface EventListenerFactory {

	//是否可以把当前方法包装成一个 ApplicationListener
   boolean supportsMethod(Method method);
	// 当前bean的名称 和 标注事件监听注解的方法 生成一个ApplicationListener
   ApplicationListener<?> createApplicationListener(String beanName, Class<?> type, Method method);

}

image-20220529155012523

具有两个实现,这EventListenerMethodProcessor使用策略模式,调用者两个类,把符合要求的方法封装成ApplicationLister对象,注册到上下文(上下文会把它们注册到多播器)

1.3把标有@EventLister注册的方法封装成ApplicationListener

在afterSingletonsInstantiated方法中实现,在bean初始化后会被容器回调使用,获取容器中所有的bean,调用processBean方法把其中标注@EventListener的方法,or @EventListener符合注册的方法,包装一个ApplicationListener 并且注册到上下文中

1.3.1获取具有@EventLister注解的方法

image-20220529160334192

1.3.2 使用对应的策略生成ApplicationListnerimage-20220529160531678

超级经典的 策略+工厂+责任链设计模式,妙呀

2.DefaultEventListenerFactory&ApplicationListenerMethodAdapter

image-20220529161241254

默认的策略,直接new 一个ApplicationListenerMethodAdapter

image-20220529161608881

2.1 ApplicationListenerMethodAdapter构造方法image-20220529162038536

这里的order 来自@Order注解 如果没有注解那么默认最低优先级,这里的condition

2.2 处理事件

image-20220529162936567

  1. 解析参数

    image-20220529163224063

  2. 反射执行

    image-20220529163440276

  3. 返回值处理

image-20220529164517503

我们可以返回CompletionStage<事件,异常>会继续推送事件

如果返回的是ListenableFuture(继承了Future)在执行完后进行回调——继续推送事件

3.TransactionalEventListenerFactory&TransactionalApplicationListenerMethodAdapter

image-20220529165340007

image-20220529170417101

TransactionSynchronizationManager 这个类有点复杂后续详细学习
  • 如果事务处于活跃状态

    image-20220529171128793

    image-20220529171157767

posted @ 2022-08-21 11:28  Cuzzz  阅读(423)  评论(0编辑  收藏  举报