• 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事件进行处理

  • 相关阅读:
    LCA + 二分(倍增)
    Educational Codeforces Round 5
    BNU 51276
    POJ 1511
    hdu2121
    最小树形图(朱刘算法)
    Educational Codeforces Round 1(D. Igor In the Museum) (BFS+离线访问)
    Educational Codeforces Round 1(C. Nearest vectors)
    POJ-2785 4 Values whose Sum is 0(折半枚举 sort + 二分)
    POJ 1661Help Jimmy(逆向DP Or 记忆化搜索 Or 最短路径)
  • 原文地址:https://www.cnblogs.com/xiaoshahai/p/16163818.html
Copyright © 2020-2023  润新知