SpringBoot (event)事件来解耦合

首先假如有这么个场景用户下单之后的操作 订单校验 ,和发送短信操作 平常会写几个service 或者biz 耦合性还是太高于是话不多说 看下面操作

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

    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 "购买成功";

    }

我们先来说同步处理 继承 ApplicationEvent这个接口 重写这个方法 给自己要到属性赋值

@ToString
public class OrderProductEvent extends ApplicationEvent {

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

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

 一下就是真正的业务实现区域

@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));
    
  }
}

===========接下来再来说说 异步

这里需要用到满参构造方法 是为了使用的时候 赋值

@Data
@AllArgsConstructor
public class MsgEvent {

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


}

然后通过一个注解 @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));
    }

}

最后像一些本身就是监听器或者是拦截器的类 咱们使用 Spring工具类来解耦合不需要注入Applicationcontext

我把这个工具类贴下面

package com.najie.activiti.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @author 7
 * @date 2022/9/22 13:46
 */
@Component
public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext = null;

    /**
     * 应用上下文赋值
     *
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (SpringUtil.applicationContext == null) {
            SpringUtil.applicationContext = applicationContext;
        }
    }

    /**
     * 获取applicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 通过name获取 Bean.
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}

我们再来看看 业务场景实际应用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值