1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 手放开 李圣杰
  4. 4 迷人的危险3(翻自 dance flow) FAFA
  5. 5 山楂树之恋 程佳佳
  6. 6 summertime cinnamons / evening cinema
  7. 7 不谓侠(Cover 萧忆情Alex) CRITTY
  8. 8 神武醉相思(翻自 优我女团) 双笙
  9. 9 空山新雨后 音阙诗听 / 锦零
  10. 10 Wonderful U (Demo Version) AGA
  11. 11 广寒宫 丸子呦
  12. 12 陪我看日出 回音哥
  13. 13 春夏秋冬的你 王宇良
  14. 14 世界が终わるまでは… WANDS
  15. 15 多想在平庸的生活拥抱你 隔壁老樊
  16. 16 千禧 徐秉龙
  17. 17 我的一个道姑朋友 双笙
  18. 18 大鱼  (Cover 周深) 双笙
  19. 19 霜雪千年(Cover 洛天依 / 乐正绫) 双笙 / 封茗囧菌
  20. 20 云烟成雨(翻自 房东的猫) 周玥
  21. 21 情深深雨濛濛 杨胖雨
  22. 22 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  23. 23 斑马斑马 房东的猫
  24. 24 See You Again Wiz Khalifa / Charlie Puth
  25. 25 Faded Alan Walker / Iselin Solheim
  26. 26 Natural J.Fla
  27. 27 New Soul Vox Angeli
  28. 28 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  29. 29 像鱼 王贰浪
  30. 30 Bye Bye Bye Lovestoned
  31. 31 Blame You 眠 / Lopu$
  32. 32 Believer J.Fla
  33. 33 书信 戴羽彤
  34. 34 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  35. 35 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  36. 36 慢慢喜欢你 LIve版(翻自 莫文蔚) 戴羽彤
  37. 37 病变(翻自 cubi) 戴羽彤
  38. 38 那女孩对我说 (完整版) Uu
  39. 39 绿色 陈雪凝
  40. 40 月牙湾 LIve版(翻自 F.I.R.) 戴羽彤
夜空中最亮的星(翻自 逃跑计划) - 戴羽彤
00:00 / 04:10

夜空中最亮的星 能否听清

那仰望的人 心底的孤独和叹息

夜空中最亮的星 能否记起

那曾与我同行 消失在风里的身影

我祈祷拥有一颗透明的心灵

和会流泪的眼睛

给我再去相信的勇气

越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请指引我靠近你

夜空中最亮的星 是否知道

那曾与我同行的身影 如今在哪里

夜空中最亮的星 是否在意

是等太阳先升起 还是意外先来临

我宁愿所有痛苦都留在心底

也不愿忘记你的眼睛

哦 给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行 哒~

我祈祷拥有一颗透明的心灵

和会流泪的眼睛 哦

给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行

初探spring事件applicationEvent

前言

不知道各位小伙伴对事件(event)这个比较抽象的名词如何理解,从我实际开发和使用经验来说,事件通常指的是某一特定条件下触发的一组操作。

做过生态开发(ISV)的小伙伴一定对事件不陌生,因为在和这些生态厂商(钉钉、企微、飞书等)进行业务交互的时候,总是避不开事件的,我们总是要对接他们的各种事件,比如入职事件、离职事件、用户变更事件、部门变更事件等等。

今天我们就来通过一个简单的示例,来演示下ApplicationListener应用级事件的使用流程。

ApplicationEvent

是什么

一个事件主要包括以下几个要素:

  • 事件注册
  • 事件监听
  • 事件触发

所以ApplicationEvent就是spring提供的一套集事件注册、监听、触发为一体的事件实现。

如何用

创建项目,增加模块配置

首先我们需要创建一个spring-boot项目,然后在项目的resouces/META-INF文件夹下增加名为spring.factories的文件,如果文件夹不存在,需要手动创建。

这个文件的作用是配置spring boot的常用组件,当然我们也可以通过注解的方式进行配置,关于注解的说明我们后面再说。

我们需要在文件中增加如下配置:

org.springframework.context.ApplicationListener=io.github.syske.springbootbeanlisttest.listener.SyskeApplicationListener

这个文件除了可以配置ApplicationListener之外,还可以配置EnvironmentPostProcessorPropertySourceLoaderSpringApplicationRunListener,这几个组件的应用,我们后期也会逐一分享。

这种配置方式其实就是SPI机制,这种配置的好处是,可以在不变更项目代码的基础上实现组件的增加和移除。

创建自己的ApplicationListener,这里需要实现ApplicationListener接口,并实现onApplicationEvent方法,事件触发时,会执行该方法。

public class SyskeApplicationListener implements ApplicationListener<SyskeApplicationEvent> {
    @Override
    public void onApplicationEvent(SyskeApplicationEvent event) {
        String eventName = event.getEventName();
        System.out.println(eventName);
        Object eventBody = event.getEventBody();
        System.out.println(eventBody);
    }
}

这个方法的入参是ApplicationEvent或者它的子类,所以这里我们可以根据需要自定义自己的事件,并继承ApplicationEvent

public class SyskeApplicationEvent extends ApplicationEvent {
  
    public SyskeApplicationEvent(Object source) {
        super(source);
    }

    private String eventName;

    private Object eventBody;
    // getter/setter方法省略
}

事件注册

因为我们是直接在spring boot项目中使用的spring的事件组件,所以我们并不需要自己去做时间的注册,因为在spring boot的启动过程中,会帮我们把事件进行注册,关于这块的内容,我在之前分享spring boot启动过程的时候已经分享过了,感兴趣的小伙伴可以去看下(时间久到我都忘记了🐶):

这里放一个启动流程的图:

从上面这个图中,我们可以清楚地看到,这里获取了所有的SpringApplicationRunListener,并分别执行了他们的startingstarted方法,但是这里的listener并不是我们的事件监听器,而是spring boot的运行监听器,但是我们事件监听器的初始化确实是在这里完成的,因为这里也初始化了我们事件的运行监听器,并执行了它的的startingstarted方法:


好了,至此,我们知道spring boot的事件是何时注册的,下面我们来一起看下事件如何触发。

事件触发

事件的触发,没啥好解释的,就是让事件监听器的onApplicationEvent方法执行

 SyskeApplicationEvent syskeApplicationEvent = new SyskeApplicationEvent("test");
        syskeApplicationEvent.setEventName("sysk-event");
        syskeApplicationEvent.setEventBody("sysk-body");
        applicationContext.publishEvent(syskeApplicationEvent);
测试
@GetMapping("/event")
    public Object testEvent() {
        SyskeApplicationEvent syskeApplicationEvent = new SyskeApplicationEvent("test");
        syskeApplicationEvent.setEventName("sysk-event");
        syskeApplicationEvent.setEventBody("sysk-body");
        applicationContext.publishEvent(syskeApplicationEvent);
        return "success";
    }

运行结果:

其实,除了我们上面展示的这种配置方式,spring boot还提供了另一套更简单便捷的事件实现方式:

@Component
public class Syske2ApplicationListenerConfig {

    @EventListener
    public void onApplicationEvent(Syske2ApplicationEvent event) {
        String eventName = event.getEventName();
        System.out.println(eventName);
        Object eventBody = event.getEventBody();
        System.out.println(eventBody);
        System.out.println("Syske2ApplicationEvent");
    }
}

也就说,我们只需要定义自己的事件,然后编写事件触发的操作方法,并在方法上加上@EventListener即可,这里的方法名无关紧要,可以随便指定,事件的触发也没有任何区别:


另外,根据实际测试发现,spring boot的事件是支持多监听的,也就是类似于广播消息,这里我两个地方都监听了同一个事件,可以看到两个地方都被触发了:

知识扩展

事件

除了今天我们介绍的ApplicationEvent之外,还有很多优秀的开源事件组件,比如guavaeventBus,后面有机会的话,我们可以单独分享下eventBus的用法。

spring.factories

在今天的内容中,我们在resouces/META-INF文件夹下,创建了spring.factories文件,其实在spring-boot的核心jar文件的META-INF文件夹也是有这个文件的,当然文件的内容更完整,它包括了以下配置:

  • 资源加载器(org.springframework.boot.env.PropertySourceLoader
  • 运行监听器(org.springframework.boot.SpringApplicationRunListener
  • 错误报告器(org.springframework.boot.SpringBootExceptionReporter
  • 应用上下文初始化组件(org.springframework.context.ApplicationContextInitializer
  • 应用监听器(org.springframework.context.ApplicationListener
  • 环境后置处理器(org.springframework.boot.env.EnvironmentPostProcessor
  • 失败分析组件(org.springframework.boot.diagnostics.FailureAnalyzer
  • 失败分析报告组件(org.springframework.boot.diagnostics.FailureAnalysisReporter

当然,并不是所有的公司都会用到事件,因为事件本身有一些局限性,比如说如果你的服务是集群环境的话,事件是不可以多节点共享的,所以很多公司可能会更愿意用mq

其实,关于事件的使用场景以及为什么要使用事件,我觉得我好像还没想明白,在我看来,事件应该是类似于异步线程池一样的存在,当然这样的思考可能有失偏薄,毕竟每一种技术的存在都是为了解决某些其他技术解决不了的问题~

好了,今天的内容就到这里吧,感谢各位小伙伴的支持,晚安哟

posted @ 2022-12-07 21:02  云中志  阅读(196)  评论(0编辑  收藏  举报