文章目录
- 前言
- 一、event是什么?
- 二、使用步骤
- 1.事件
- 2.事件监听
- 3.发布事件
- 三、测试结果
- 总结
 
前言
项目中的业务难免是相互关联的,但是代码中我们应该尽量做到低耦合,常见的做法就是引入mq来作为松耦合的一种手段;
 其实最常见的解耦和就是接口了,MVC直接通过接口(约定好的一种规则)相互调用,都是解耦的一种体现;
 还有就是springbean aop等 也就是IOC 都是解耦和的场景;
通常mq是我们的选择,但是当仅仅是为了解耦的简单业务场景,其实完全没必要引入mq,而spring中的event则就可以实现解耦~
一、event是什么?
使用场景 一处变动影响范围较大,如果都将代码写在一起会造成耦合很高,这样利用event或者mq 可以解耦
当下单成功后:
 1 扣减库存
 2 维护个人信息
 3 物流信息
 4 订单流水
 5 商品销量
 6 …
event 是spring提供的,在 org.springframework.context.event 中
 它由三部分组成:
- 事件
- 事件监听
- 事件发布
二、使用步骤
1.事件
声明一个类,继承ApplicationEvent 即可,然后可以放入一个自己创建的作为信息传递的载体(Bom), 这个Bom可有可无
public class DemoEvent extends ApplicationEvent {
    private Bom bom;
    public DemoEvent(Bom source) {
        super(source);
        this.bom = source;
    }
    public Bom getBom() {
        return bom;
    }
}2.事件监听
事件监听有两种方式: 1 注解 2 实现ApplicationListener接口 其实都是一个意思 3 条件过滤
- 注解 可以同监听多个类
@Slf4j
@Component
public class DemoEventListener {
    @EventListener(classes = DemoEvent.class)
    public void listener(DemoEvent event) {
        log.info(JSONUtil.toJsonStr(event));
    }
}- 实现接口
@Slf4j
@Component
public class DemoEventListener1 implements ApplicationListener<DemoEvent> {
    @Override
    public void onApplicationEvent(DemoEvent event) {
        log.info(JSONUtil.toJsonStr(event));
    }
}- 注解的基础上,再次过滤
@Slf4j
@Component
public class DemoEventListener2 {
    @EventListener(condition = "#root.event.bom.f4.equals('2')")
    public void listener(DemoEvent event) {
        log.info(JSONUtil.toJsonStr(event));
    }
}其中 #root.event.bom.f4 就是条件
 #root.event 固定的
 bom 是我们在事件中自定义的参数名称
 f4 是其中的一个属性名称
还可以这样写:
@EventListener(condition = “#root.getEvent().getBom().getF4().equals(‘2’)”)
 这样更好理解哈~
3.发布事件
搞一个测试类
@SpringBootTest
class DemoEventListenerTest {
    @Autowired
    ApplicationEventPublisher applicationEventPublisher;
    @Test
    public void publishPersonSaveEvent(){
        Bom bom = new Bom();
        bom.setF4("12");;
        bom.setF6("12");
        DemoEvent demoEvent = new DemoEvent(bom);
        applicationEventPublisher.publishEvent(demoEvent);
        bom.setF4("2");;
        bom.setF6("12");
        applicationEventPublisher.publishEvent(new DemoEvent(bom));
    }
}三、测试结果

可以看到两个监听类中都接受到了ApplicationEventPublisher 发布者发布的消息内容;
 但是 DemoEventListener2 由于根据条件过滤,只接受到了一条消息;
总结
对于这种简单的业务解耦,我们应该优先选择spring提供的event事件,可以减少引入的mq造成项目扩张,对于不熟悉的人员造成学习成本,有利于项目的快速推进;
 但是当复杂业务的时候,或者有类似其他项目业务要同种解耦的场景,依然还是引入mq为主,看场景合适,各取所需吧;
event可以实现一对多,文中的例子, 一个消息,多处消费并处理
 event可以实现多对一, 文中的注解可以同时监听多个事件 @EventListener(classes = {A.class, B.class})
 event支持事物,当事件处理失败,会回滚
                










