【Spring】事件发布与@EventListener

121 阅读2分钟

事件机制可以将同一个应用系统内互相耦合的代码进行解耦,并且可以将事件与 Spring 事务结合起来,实现我们工作中的一些业务需求。

文件结构

在这里插入图片描述

实现

MainApplication

MainApplication.java

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync
@SpringBootApplication
public class MainApplication {

    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class, args);
    }
}

common.OrderCreateEvent

OrderCreateEvent.java

package org.example.common;

import lombok.Data;
import org.springframework.context.ApplicationEvent;

@Data
public class OrderCreateEvent extends ApplicationEvent {

    public Object log;

    /**
     * @param log    需要传递的参数
     * @param source 事件源对象
     */
    public OrderCreateEvent(Object source, Object log) {
        super(source);
        this.log = log;
    }
}

common.OrderEvent

OrderEvent.java

package org.example.common;

import lombok.Data;
import org.springframework.context.ApplicationEvent;

@Data
public class OrderEvent extends ApplicationEvent {

    public Object log;

    private Integer status;

    private Integer exists = 0;

    private Integer async = 0;

    /**
     * @param log    需要传递的参数
     * @param source 事件源对象
     */
    public OrderEvent(Object source, Object log) {
        super(source);
        this.log = log;
    }
}

controller.HelloController

HelloController.java

package org.example.controller;

import org.example.service.OrderService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;


@RestController
public class HelloController {

    @Autowired
    private OrderService orderService;

    @PostMapping("/event-publish")
    public void eventPublish() {
        orderService.submit();
    }

    @PostMapping("/event-publish2")
    public void eventPublish2() {
        orderService.submit2();
    }

    @PostMapping("/event-publish3")
    public void eventPublish3() {
        orderService.submit3();
    }

    @PostMapping("/event-publish4")
    public void eventPublish4() {
        orderService.submit4();
    }
}


service.OrderService

OrderService.java

package org.example.service;

import lombok.extern.slf4j.Slf4j;
import org.example.common.OrderCreateEvent;
import org.example.common.OrderEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class OrderService {

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    /**
     * 订单提交
     */
    public void submit() {
        OrderCreateEvent orderCreateEvent = new OrderCreateEvent(this, "创建订单");
        log.info("提交订单前....");
        // 发布事件
        applicationEventPublisher.publishEvent(orderCreateEvent);
        log.info("提交订单后....");
    }


    public void submit2() {
        log.info("提交订单前....");
        OrderEvent orderEvent = new OrderEvent(this, "提交订单事件2");
        orderEvent.setStatus(1);
        // 发布事件
        applicationEventPublisher.publishEvent(orderEvent);
        log.info("提交订单后....");
    }

    public void submit3() {
        log.info("提交订单前....");
        OrderEvent orderEvent = new OrderEvent(this, "提交订单事件3");
        orderEvent.setStatus(1);
        orderEvent.setExists(1);
        // 发布事件
        applicationEventPublisher.publishEvent(orderEvent);
        log.info("提交订单后....");
    }

    public void submit4() {
        log.info("提交订单前....");
        OrderEvent orderEvent = new OrderEvent(this, "提交订单事件4");
        orderEvent.setAsync(1);
        // 发布事件
        applicationEventPublisher.publishEvent(orderEvent);
        log.info("提交订单后....");
    }
}

service.OrderLogService

OrderLogService.java

package org.example.service;

import lombok.extern.slf4j.Slf4j;
import org.example.common.OrderCreateEvent;
import org.example.common.OrderEvent;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.event.TransactionalEventListener;

@Service
@Slf4j
public class OrderLogService {

    /**
     * 条件事件监听
     * @param OrderCreateEvent orderCreateEvent
     */
    @EventListener(classes = {OrderCreateEvent.class})
    public void listen(OrderCreateEvent orderCreateEvent) {
        log.info("事件监听:{}", orderCreateEvent.getLog());
        try {
            // 验证事件的同步
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 条件事件监听2
     * @param OrderEvent event
     */
    @EventListener(condition = "#event.status == 1 && #event.exists == 0")
    public void listen2(OrderEvent event) {
        log.info("事件监听:{}, event.status = {}", event.getLog(), event.getStatus());
        try {
            // 验证事件的同步
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 条件事件监听3
     * @param OrderEvent event
     */
    @EventListener(condition = "#event.status == 1 && #event.exists == 1")
    public void listen3(OrderEvent event) {
        log.info("事件监听:{}, event.status = {}, event.exist = {}", event.getLog(), event.getStatus(), event.getExists());
        try {
            // 验证事件的同步
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 异步事件监听
     * @param event
     */
    @Async
    @EventListener(condition = "#event.async == 1")
    public void listen4(OrderEvent event) {
        try {
            // 验证事件的异步
            Thread.sleep(5000);
            log.info("异步事件监听:{}", event.getLog());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

结果

POST http://localhost:8080/event-publish

在这里插入图片描述

POST http://localhost:8080/event-publish2

在这里插入图片描述

POST http://localhost:8080/event-publish3

在这里插入图片描述

POST http://localhost:8080/event-publish4

在这里插入图片描述

参考

blog.csdn.net/mu_se_yao_r…