Development actual combat-I used Spring's event monitoring mechanism to achieve module decoupling

 

background

Here we have a requirement:

When the user pays successfully, the order status needs to be modified; the user is notified by SMS; the warehouse is notified to ship

Original solution

This must be the first thing you think of

public void paySuccess(String orderId) {
    if (StringUtils.isNotBlank(orderId)) {
        //1.修改订单状态
        //2.发送短信通知用户
        //3.通知仓库发货
    }
}

In the method of successful payment, call the method of modifying the order, call the method of SMS notification to the user, and call the method of warehouse delivery. It's over, you think it's very simple.

However, the product manager said that I need to change my requirements. Not only do I need SMS notifications, but I also need WeChat notifications. This is still simple.

if (StringUtils.isNotBlank(orderId)) {
    //1.修改订单状态
    //2.发送短信通知用户
    //3.通知仓库发货
    //4.微信通知
}

After a day, the product manager came to add demand again, and I still can notify by QQ, which is not difficult.

if (StringUtils.isNotBlank(orderId)) {
    //1.修改订单状态
    //2.发送短信通知用户
    //3.通知仓库发货
    //4.微信通知
    //5.QQ通知
}

A month later, the product manager came again: "Add a feature to me. After I have paid successfully, I can also issue coupons and points..."

The requirements are endless, but at this time you have forgotten where the code for successful payment is written.

Finally, you find it and start writing. Suddenly, you realize, that's wrong, this method is getting bloated. And every time you have to modify the method of successful payment, what if you modify the error.

You are also aware of a problem. These functions are all synchronized. If I fail to call the WeChat notification function, can I not notify by QQ or issue coupons? Roll back all of them. It's too unreasonable.

You are thinking hard and you have learned that an event monitoring mechanism can be asynchronously decoupled. Isn't it suitable for this scenario? Just do it, code refactoring starts.

Event monitoring solution

I won't talk about the event monitoring mechanism here. There are a lot of concepts about Baidu. I will start with actual examples to let you thoroughly understand what this mechanism does and when to use it.

Let's first define a payment event class

/**
 * Description: 支付事件
 *
 * @author Lvshen
 * @version 1.0
 * @date: 2020-8-28 13:56
 * @since JDK 1.8
 */
public class PayEvent extends ApplicationEvent {
    //订单id
    private String orderId;

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

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

The payment service class is written like this

/**
 * Description:支付服务
 *
 * @author Lvshen
 * @version 1.0
 * @date: 2020-8-28 14:02
 * @since JDK 1.8
 */
@Component
public class PayService {

    @Autowired
    public ApplicationEventPublisher applicationEventPublisher;

    /**
     * 支付成功后,发布事件
     * @param orderId
     */
    public void paySuccess(String orderId) {
        if (StringUtils.isNotBlank(orderId)) {
            applicationEventPublisher.publishEvent(new PayEvent(this, orderId));
        }
    }
}

After the payment is successful, the event will be released. The requirement here is to notify the user by SMS after payment, notify the order modification status, and notify the warehouse to prepare for shipment. We respectively create related classes to receive the published events.

OrderService

/**
 * Description:订单服务
 *
 * @author Lvshen
 * @version 1.0
 * @date: 2020-8-28 14:10
 * @since JDK 1.8
 */
@Component
public class OrderService {

    @EventListener
    public void updateOrderStatus(PayEvent payEvent) {
        String orderId = payEvent.getOrderId();
        //修改订单状态
        System.out.println(String.format("支付成功,修改订单【%s】状态为已支付!!!",orderId));
    }
}

When the order service monitors the data sent by the payment service, it starts to modify the data.

SmsService

/**
 * Description:短信服务
 *
 * @author Lvshen
 * @version 1.0
 * @date: 2020-8-28 14:16
 * @since JDK 1.8
 */
@Component
public class SmsService {

    @EventListener
    public void sendMessage(PayEvent payEvent) {
        String orderId = payEvent.getOrderId();
        //短信功能
        System.out.println(String.format("支付成功,发送【%s】短信",orderId));
    }
}

The SMS service monitors payment events. When the payment is successful, it monitors the event and sends a message of successful payment to the user.

WarehouseService

/**
 * Description:仓库服务
 *
 * @author Lvshen
 * @version 1.0
 * @date: 2020-8-28 14:21
 * @since JDK 1.8
 */
@Component
public class WarehouseService {
    @EventListener
    public void sendProduct(PayEvent payEvent) {
        String orderId = payEvent.getOrderId();
        //发货功能
        System.out.println(String.format("支付成功,准备发货,订单【%s】",orderId));
    }
}

Similarly, when the warehouse monitors the payment success event, it starts to prepare for delivery.

Test event release mechanism [ie when payment is successful]

show result

 

When you need to add WeChat notifications, you only need to write a WeChat service class to monitor the payment success event. In the same way, QQ notification and coupon distribution, points distribution and other functions use the same method.

In this way, we don't have to change the payment success method, after all, it is still very dangerous to modify the core method.

Here I throw 2 questions:

1. If the transaction has not been submitted after the event is released, and the other side listens to it, it may cause data inaccuracy and null pointer exceptions.

2. If the party that publishes the event has an operating database, the party that monitors the event also has an operating database. When an exception is thrown when the party listening to the event operates the database, does the party publishing the event need to roll back?

I wonder what is your solution to these two problems?

Recommended in the past

Scan the QR code to get more exciting. Or search Lvshen_9 on WeChat , you can reply to get information in the background

1.回复"java" 获取java电子书;

2.回复"python"获取python电子书;

3.回复"算法"获取算法电子书;

4.回复"大数据"获取大数据电子书;

5.回复"spring"获取SpringBoot的学习视频。

6.回复"面试"获取一线大厂面试资料

7.回复"进阶之路"获取Java进阶之路的思维导图

8.回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)

9.回复"总结"获取Java后端面试经验总结PDF版

10.回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)

11.回复"并发导图"获取Java并发编程思维导图(xmind终极版)

Another: Click [ My Benefits ] to have more surprises.

Guess you like

Origin blog.csdn.net/wujialv/article/details/108437884