SpringApplicationEvent的使用方式
SpringApplicationEvent 是Spring提供的事件的一种编程范式,基于此我们可以监听SpringApplication的一些事件,或者自定事件来实现解耦操作。
对于自定义SpringEvent而言,我们可以定义自己的事件,比如
public class CustomerEvent extends ApplicationEvent {public CustomerEvent(Object source) {super(source);}}
对于此类事件,如果需要对其事件进行监听,我们可以通过三种方式来实现。
/** 自定义事件监听器,继承ApplicationLitener */@Componentclass CustomerEventListener implements ApplicationListener<CustomerEvent> {@Overridepublic void onApplicationEvent(@NotNull CustomerEvent event) {}}// 在一个普通方法上标注注解 @EventListener@Componentpublic class CustomerEventListener {@EventListenerpublic void handler(CustomerEvent event) {}}// 或者在SPring启动的代码中添加监听器public static void main(){ConfigurableApplicationContext context = new SpringApplicationBuilder(Application.class).run(args);context.addApplicationListener(new CustomerEventListener());}// 或者在application.ymal文件中配置context.lsitener.classes=xxxx// 或者在WEB-INF/spring.factories文件中配置 org.springframework.context.ApplicationListener=xxx
如果要测试事件的发送以及处理,则可以使用上下文发送事件,比如 context.publishEvent(new CustomerEvent());
SpringApplicationEvent的实现原理
这里以SpringApplicationStartingEvent事件为例,展示SpringBoot在启动中是如何触发。SpringApplication 对象构建完成之后,在调用的run()方法中,有以下代码
public ConfigurableApplicationContext run(String... args) {// .....SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();// .....}// getSpringFactoriesInstances 中获取 SpringApplicationRunListener// getSpringFactoriesInstances 方法已经看到,就是从spring.factories 中获取RunListenerprivate SpringApplicationRunListeners getRunListeners(String[] args) {Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };// 构造一个 SpringApplicationRunListeners 对象return new SpringApplicationRunListeners(logger,getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));}class SpringApplicationRunListeners {private final Log log;private final List<SpringApplicationRunListener> listeners;SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) {this.log = log;this.listeners = new ArrayList<>(listeners);}void starting() {// 遍历发送for (SpringApplicationRunListener listener : this.listeners) {listener.starting();}}}public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {@Overridepublic void starting() {// 调用 initialMulticaster 广播器 发送this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));}@Overridepublic void environmentPrepared(ConfigurableEnvironment environment) {// 和Starting类似,构造环境准备完成this.initialMulticaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));}}
比如后台任务就对 SpringApplicationEvent 感兴趣,所以其可以注册到该事件
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); }
```
控制台日志中,就可以看到:
