Spring Event使用

2/24/2023 Spring

# Spring Event 同步使用

  • Spring EventApplication Event)其实就是一个观察者设计模式,一个 Bean 处理完成任务后希望通知其它 Bean 或者说一个 Bean 想观察监听另一个Bean 的行为。

# 1. 自定义事件

  • 定义事件,继承 ApplicationEvent 的类成为一个事件类
@Data
@ToString
public class OrderProductEvent extends ApplicationEvent {

  /** 该类型事件携带的信息 */
  private String orderId;

  public OrderProductEvent(Object source, String orderId) {
    super(source);
    this.orderId = orderId;
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13

# 2. 定义监听器

  • 监听并处理事件,实现 ApplicationListener 接口或者使用 @EventListener 注解
/**
 * 实现 ApplicationListener 接口,并指定监听的事件类型
 */
@Slf4j
@Component
public class OrderProductListener implements ApplicationListener<OrderProductEvent> {

  /** 使用 onApplicationEvent 方法对消息进行接收处理 */
  @SneakyThrows
  @Override
  public void onApplicationEvent(OrderProductEvent event) {
    String orderId = event.getOrderId();
    long start = System.currentTimeMillis();
    Thread.sleep(2000);
    long end = System.currentTimeMillis();
    log.info("{}:校验订单商品价格耗时:({})毫秒", orderId, (end - start));
  }
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 3. 定义发布者

  • 发布事件,通过ApplicationEventPublisher 发布事件
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderService {

  /** 注入ApplicationContext用来发布事件 */
  private final ApplicationContext applicationContext;

  /**
   * 下单
   *
   * @param orderId 订单ID
   */
  public String buyOrder(String orderId) {
    long start = System.currentTimeMillis();
    // 1.查询订单详情

    // 2.检验订单价格 (同步处理)
    applicationContext.publishEvent(new OrderProductEvent(this, orderId));

    // 3.短信通知(异步处理)

    long end = System.currentTimeMillis();
    log.info("任务全部完成,总耗时:({})毫秒", end - start);
    return "购买成功";
  }
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# Spring Event 异步使用

# 1. 自定义事件

@Data
@AllArgsConstructor
public class MsgEvent {

   /** 该类型事件携带的信息 */
   public String orderId;
}
1
2
3
4
5
6
7

# 2. 定义监听器,使用@EventListener注解

@Slf4j
@Component
public class MsgListener {

  // 开启异步
  @Async
  @SneakyThrows
  @EventListener(MsgEvent.class)
  public void sendMsg(MsgEvent event) {
    String orderId = event.getOrderId();
    long start = System.currentTimeMillis();
    log.info("开发发送短信");
    log.info("开发发送邮件");
    Thread.sleep(4000);
    long end = System.currentTimeMillis();
    log.info("{}:发送短信、邮件耗时:({})毫秒", orderId, (end - start));
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 3. 定义发布者

public String buyOrder(String orderId) {
    long start = System.currentTimeMillis();
    // 1.查询订单详情

    // 2.检验订单价格 (同步处理)
    applicationContext.publishEvent(new OrderProductEvent(this, orderId));

    // 3.短信通知(异步处理)
    applicationContext.publishEvent(new MsgEvent(orderId));

    long end = System.currentTimeMillis();
    log.info("任务全部完成,总耗时:({})毫秒", end - start);
    return "购买成功";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14