目录
一、Spring中的事件监听
二、自定义事件监听
三、例子
1、事件
2、事件监听器
3、事件发布操作
三、测试注意
一、Spring中的事件监听
- 当处理完一段代码逻辑,后面需要同时执行多个任务,有什么好方法呢?如果在微服务项目中,可以使用MQ;但如果是单机,spring为我们提供了事件监听。
- 在一个Spring容器中,我们可以发送消息给Spring容器,容器收到消息后自动接受消息并进行处理
- 本质上是观察者模式。 Observer Pattern也叫作发布订阅模式Publish/Subscribe。定义对象间一对多的依赖关系,使得每当一个对象改变状态,则所有依赖与它的对象都会得到通知,并被自动更新。
-
观察者模式的优点。 观察者和被观察者之间是抽象耦合,不管是增加观察者还是被观察者都非常容易扩展。建立一套触发机制。
-
使用场景
关联行为场景是可拆分的。
事件多级触发场景
二、自定义事件监听
- 事件监听主要有两部分组成,一个是事件源,另一个是监听事件并处理的对象
- 核心事项:自定义事件,自定义监听器,并将监听器注册到Spring容器中即可
三、例子
1、事件
Spring事件对象为ApplicationEvent,继承自ObjectEvent
import org.springframework.context.ApplicationEvent;
public class TestEvent extends ApplicationEvent {
private int id;
private String name;
private int age;
public TestEvent(Object source, int id, String name, int age) {
super(source);
this.name = name;
this.age = age;
this.id = id;
}
public String getName() {
return name;
}
public String getAge() {
return age;
}
public String getId() {
return id;
}
}
2、事件监听器
当事件对象被发布到Spring后,将会找出对应的监听器对事件进行处理
Spring中的事件监听器为ApplicationListener,继承自EventListener
说明: 同一个事件TestEvent, 可以有多个监听器(如 TestEventListener1,TestEventListener2)
@Component
public class TestEventListener1 implements ApplicationListener<TestEvent> {
private static final Logger logger = LoggerFactory.getLogger(TestEventListener.class);
@Override
public void onApplicationEvent(TestEvent event) {
logger.info("receive event : {} ",event);
//处理
}
}
@Component
public class TestEventListener2 implements ApplicationListener<TestEvent> {
private static final Logger logger = LoggerFactory.getLogger(TestEventListener.class);
@Override
public void onApplicationEvent(TestEvent event) {
logger.info("receive event : {} ",event);
//处理
}
}
3、事件发布操作
方法一:
定义:TestApplicationContext
@Component
public class TestApplicationContext implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static ApplicationContext getContext() {
return context;
}
}
使用:TestApplicationContext发布事件
TestApplicationContext.getContext().publishEvent(new TestEvent("object",1,"nameTest",25));
方法二:
nnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext();
// 注册自定义事件监听器
context.addApplicationListener(new TestEventListener1());
context.addApplicationListener(new TestEventListener2());
// 启动上下文
context.refresh();
// 发布事件
context.publishEvent(new TestEvent("object",1,"nameTest",25));
// 结束
context.close();
方法三:
@Autowired
private WebApplicationContext webApplicationContext;
webApplicationContext.publishEvent(new TestEvent("object",1,"nameTest",25));
事件监听器一定要写一个类去实现吗 -- 其实是可以不需要的,spring有个注解@EventListener,修饰在方法上即可。如:
@Lazy
@Slf4j
@Component
public class TestEventListener extends CommonListener {
@EventListener(value = {TestEvent.class})
public void handle(AuditRefuseEvent event) {
//处理即可
}
}
EventListener也可以接受参数, 来表示事件源的,有两个参数classes和condition,顾明思议前者是表示哪一个事件类,后者是当满足什么条件是会调用该方法.
三、测试注意
- 单个业务场景下,监听逻辑处理正常;
- 异常业务场景下,做了兼容处理;
- 并发业务操作,监听逻辑处理正常;