spring事件监听event(默认的mq)


前言

项目中的业务难免是相互关联的,但是代码中我们应该尽量做到低耦合,常见的做法就是引入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. 事件
  2. 事件监听
  3. 事件发布

二、使用步骤

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 条件过滤

  1. 注解 可以同监听多个类
@Slf4j
@Component
public class DemoEventListener {
    
    

    @EventListener(classes = DemoEvent.class)
    public void listener(DemoEvent event) {
    
    
        log.info(JSONUtil.toJsonStr(event));
    }
}
  1. 实现接口
@Slf4j
@Component
public class DemoEventListener1 implements ApplicationListener<DemoEvent> {

    @Override
    public void onApplicationEvent(DemoEvent event) {
        log.info(JSONUtil.toJsonStr(event));
    }
}
  1. 注解的基础上,再次过滤
@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支持事物,当事件处理失败,会回滚

猜你喜欢

转载自blog.csdn.net/qq_32419139/article/details/132289445