Spring的事件监听机制(一)
先看一段问题代码。如果我们要实现一个主线业务,同时需要做一些支线任务。如果都写在一起,会不太好,我们不希望把主线任务耦合到支线任务里面。
package com.example.springdemo.demos.a17;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;/*** @author zhou* @version 1.0* @description TODO* @date 2025/9/6 21:56*/
@Configuration
public class TestListener {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestListener.class);context.getBean(MyService.class).doBusiness();context.close();}@Componentstatic class MyService{private static final Logger log = LoggerFactory.getLogger(TestListener.class);public void doBusiness(){log.debug("主线业务");log.debug("发送短信");log.debug("发送邮件");}}
}
Spring提供了事件监听机制去实现主线任务与支线任务的低耦合。实现思路如下:
1.首先需要提供事件对象
static class MyEvent extends ApplicationEvent{public MyEvent(Object source) {super(source);}}
2.实现Spring提供的事件监听器接口,并指定泛型接口是我们自己写的事件对象。重写里面的方法加上我们自己的逻辑。
@Componentstatic class SmsApplicationListener implements ApplicationListener<MyEvent>{private static final Logger log = LoggerFactory.getLogger(SmsApplicationListener.class);@Overridepublic void onApplicationEvent(MyEvent event) {log.debug("发送短信");}}
@Componentstatic class EmailApplicationListener implements ApplicationListener<MyEvent>{private static final Logger log = LoggerFactory.getLogger(EmailApplicationListener.class);@Overridepublic void onApplicationEvent(MyEvent event) {log.debug("发送邮件");}}
3.改造业务代码
注入事件发布器发布事件。
@Componentstatic class MyService{private static final Logger log = LoggerFactory.getLogger(TestListener.class);@Autowiredprivate ApplicationEventPublisher publisher;public void doBusiness(){log.debug("主线业务");/* log.debug("发送短信");log.debug("发送邮件");*/publisher.publishEvent(new MyEvent("MyService.doBusiness()"));}}
其中MyEvent
构造函数的参数可以是任何有助于监听器理解"发生了什么"和"需要处理什么"的信息,而不仅仅是方法名。
打印结果:
这里监听器执行支线任务是随机的,而且都是在主线程执行,还有优化空间。