SpringApplicationEvent的使用方式

SpringApplicationEvent 是Spring提供的事件的一种编程范式,基于此我们可以监听SpringApplication的一些事件,或者自定事件来实现解耦操作。
对于自定义SpringEvent而言,我们可以定义自己的事件,比如

  1. public class CustomerEvent extends ApplicationEvent {
  2. public CustomerEvent(Object source) {
  3. super(source);
  4. }
  5. }

对于此类事件,如果需要对其事件进行监听,我们可以通过三种方式来实现。

  1. /** 自定义事件监听器,继承ApplicationLitener */
  2. @Component
  3. class CustomerEventListener implements ApplicationListener<CustomerEvent> {
  4. @Override
  5. public void onApplicationEvent(@NotNull CustomerEvent event) {}
  6. }
  7. // 在一个普通方法上标注注解 @EventListener
  8. @Component
  9. public class CustomerEventListener {
  10. @EventListener
  11. public void handler(CustomerEvent event) {}
  12. }
  13. // 或者在SPring启动的代码中添加监听器
  14. public static void main(){
  15. ConfigurableApplicationContext context = new SpringApplicationBuilder(Application.class).run(args);
  16. context.addApplicationListener(new CustomerEventListener());
  17. }
  18. // 或者在application.ymal文件中配置context.lsitener.classes=xxxx
  19. // 或者在WEB-INF/spring.factories文件中配置 org.springframework.context.ApplicationListener=xxx

如果要测试事件的发送以及处理,则可以使用上下文发送事件,比如 context.publishEvent(new CustomerEvent());

SpringApplicationEvent的实现原理

这里以SpringApplicationStartingEvent事件为例,展示SpringBoot在启动中是如何触发。SpringApplication 对象构建完成之后,在调用的run()方法中,有以下代码

  1. public ConfigurableApplicationContext run(String... args) {
  2. // .....
  3. SpringApplicationRunListeners listeners = getRunListeners(args);
  4. listeners.starting();
  5. // .....
  6. }
  7. // getSpringFactoriesInstances 中获取 SpringApplicationRunListener
  8. // getSpringFactoriesInstances 方法已经看到,就是从spring.factories 中获取RunListener
  9. private SpringApplicationRunListeners getRunListeners(String[] args) {
  10. Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
  11. // 构造一个 SpringApplicationRunListeners 对象
  12. return new SpringApplicationRunListeners(logger,
  13. getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
  14. }
  15. class SpringApplicationRunListeners {
  16. private final Log log;
  17. private final List<SpringApplicationRunListener> listeners;
  18. SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) {
  19. this.log = log;
  20. this.listeners = new ArrayList<>(listeners);
  21. }
  22. void starting() {
  23. // 遍历发送
  24. for (SpringApplicationRunListener listener : this.listeners) {
  25. listener.starting();
  26. }
  27. }
  28. }
  29. public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
  30. @Override
  31. public void starting() {
  32. // 调用 initialMulticaster 广播器 发送
  33. this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
  34. }
  35. @Override
  36. public void environmentPrepared(ConfigurableEnvironment environment) {
  37. // 和Starting类似,构造环境准备完成
  38. this.initialMulticaster
  39. .multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
  40. }
  41. }

比如后台任务就对 SpringApplicationEvent 感兴趣,所以其可以注册到该事件

  1. public class BackgroundPreinitializer implements ApplicationListener<SpringApplicationEvent> {}
  • 这里我们也可以定义一个ApplicationListener 对 ApplicationEvent 监控,代码如下: ```java public class SelfApplicationEventListener implements ApplicationListener {

    private static final Logger log = LoggerFactory.getLogger(SelfApplicationEventListener.class);

    @Override public void onApplicationEvent(ApplicationEvent event) { log.info(“接收到 :{} “, event.getClass()); } }

// 同时需要添加到 META-INF/spring.factories 文件中 org.springframework.context.ApplicationListener=\ com.zhoutao123.spring.springboot.event.SelfApplicationEventListener

// 或者在SpringApplication中添加 public static void main(String[] args) { SpringApplication application = new SpringApplication(Application.class); application.addListeners(new SelfApplicationEventListener()); application.run(args); }

```

控制台日志中,就可以看到: