spring监听

### spring监听

本篇需要解决的问题
  1. spring如何避免读取不到完整的bean
  2. 怎么样可以在所有bean创建完之后做扩展代码
  3. 介绍spring事件监听的原理
问题解答
  1. spring如何避免读取不到完整的bean:简单来说加锁,第一处, getSingleton(String beanName, boolean allowEarlyReference) ,第二处 getSingleton(String beanName, ObjectFactory<?> singletonFactory),

1650271651335

1650271878470

  1. 怎么样在所有bean创建完后做扩展:
    1. 监听容器完成事件 contextRefreshedEvent
    2. 实现SmartInitializingSingleton接口的afterSingletonsInstantiated
  2. 接受spring监听器原理
    1. 用了观察者模式
    2. 启动容器的时候refresh()中有一个 initApplicationEventMulticaster (),这里面创建多播器,注册 SimpleApplicationEventMulticaster (),
    3. 实现接口,或者注解注册监听器
    4. 创建事件
    5. 发布事件到多播器,他就会通知其他监听器。
使用spring事件
  1. spring事件体系包括三个组件:事件。事件监听器,事件广播器
  2. spring内置事件,由系统内部进行发布,只需要注入监听器
  3. 1650264916461
  4. 1650264927191
  5. 自定义事件,需要继承applicationEvent,或者实现接口ApplicationListener,并且加上@Component托管给spring,也可以基于注解@EventListener
  6. 事件发布:applicationContext.publishEvent();

1650265192016

  1. 面临的一些问题

    1. 同样的事件能有多个监听器吗--可以
    2. 事件监听器一定要写一个类去实现吗?--可以不用,通过注解EventListener,修饰在方法上
    3. 事件监听操作和发布事件操作是同步吗?--是的,
    4. 可以异步处理吗--可以,看代码如下
    5. 1650265413608
    6. 1650265430374
  2. spring事件原理

    1. 原理:观察者模式

    2. spring事件监听三部分,分别是事件,监听器,事件发布器

    3. 事件 applicationEvent,负责对应相应的监听器,事件源发生某些事件是特定事件监听器被触发

    4. 监听器 applicationListener,对应于观察者模式中的观察者,监听器监听特定事件,并在内部定义了事件发生后的相应逻辑

    5. 事件发布器 applicationEventmulticaster 对应观察模式中的被观察者/主题,负责通知观察者对外提供发布事件和增删事件监听器的接口,维护事件和事件监听器之间的映射关系,并在事件发生时负责通知相关监听器

    6. spring事件机制是观察者模式的一种实现,除了发布者和监听者俩个角色之外,还有一个eventMulticaster的角色负责把事件转发给监听者,其流程如下

    7. 1650265875126

    8. 发布者调用applicatonEventPublisher.publishEvent(msg); 会将事件发送给eventMulticaster,然后尤其根据事件类型转发给对应的listerner.

    9. 源码流程如下:==========================

    10. Spring在ApplicationContext接口的抽象实现类AbstractApplicationContext中完成了事件体系的搭建。

      AbstractApplicationContext拥有一个applicationEventMulticaster成员变量,

      applicationEventMulticaster提供了容器监听器的注册表。

      AbstractApplicationContext在refresh()这个容器启动方法中搭建了事件的基础设施,其中

      AbstractApplicationContext的refresh方法实现如下:

      initApplicationEventMulticaster
      
    11. 事件广播器的初始化

    12. 1650267155457

    13. 用户可以在配置文件中为容器定义一个自定义的事件播放器,只要实现applicationEventMulticaster,spring会通过反射的机制将其注册成容器的事件播放器,如果没有找到配置的外部事件广播器,spring自动使用simpleApplicationEventMulticaster作为事件广播器。

    14. 注册事件监听器

    15. 1650267762404

      spring根据反射机制,使用listableBeanFactory的getBeansOfType方法,从beanDefinitionRegistry中找到所有实现applicationListener的Bean,将他们注册为容器的事件监听器监听,将其添加到事件广播器所提供的监听器注册表中。

    16. 发布事件,看finishRefresh();publishEvent

    17. 1650270738697

    18. 1650270747603

    19. 在abstractApplicationContext的publishEvent中,spring委托applicationEventMulticaster将事件通知给所有的事件监听器

    20. spring默认的事件广播器simpleApplicationEventMulticaster

    21. 1650270921151

    22. 1650270947647

    23. 遍历注册的每个监听器,并启动来调用每个监听器的onApplicaitonEvent方法,由于simpleApplicationEventMulticaster的taskExecutor的实现类是syncTaskExecutor,因此,事件监听器对事件的处理是同步的。如果想异步处理,需要手动实现applicationEveentMulticaster接口,并在spring容器中注册id为spplicationEventMulticaster的bean,下面是例子

    24. 1650271216780

    25. 1650271230274

    26. spring发布事件之后,所有注册的事件监听器,都会受到该事件,因此,事件监听器在处理事件时,需要先判断该事件是否是自己监听的。

    27. spring事件体系使用的是观察者模式,applicationListener是观察者的接口,接口中定义了onApplicationEvent方法,作用是对applicationEvent事件进行处理

posted @ 2022-04-19 09:25  小傻孩丶儿  阅读(124)  评论(0编辑  收藏  举报