実際の戦闘の開発-モジュールのデカップリングを実現するためにSpringのイベント監視メカニズムを使用しました

 

バックグラウンド

ここに要件があります:

「「

ユーザーが正常に支払いを済ませたら、注文ステータスを変更する必要があります。ユーザーにはSMSで通知され、倉庫には出荷が通知されます。

元のソリューション

これはあなたが最初に考えることでなければなりません

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

支払い成功の方法で、注文を変更する方法を呼び出し、ユーザーにSMS通知の方法を呼び出し、倉庫配送の方法を呼び出します。それは終わった、あなたはそれがとても簡単だと思う。

ただし、製品マネージャーから、要件を変更する必要があると言われました。SMS通知だけでなく、WeChat通知も必要です。これはまだ簡単です。

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

1日後、プロダクトマネージャーが再び需要を追加するようになりましたが、それでもQQで通知できますが、難しいことではありません。

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

1か月後、製品マネージャーが再び来ました。「機能を追加してください。支払いが完了したら、クーポンやポイントを発行することもできます...」

要件は無限ですが、現時点では、支払いを成功させるためのコードがどこに書かれているかを忘れています。

最後に、それを見つけて書き始めます。突然、あなたはそれが間違っていることに気づきます、この方法は肥大化しています。また、支払いの成功方法を変更する必要があるたびに、エラーを変更するとどうなりますか。

また、問題を認識しています。これらの機能はすべて同期されています。WeChat通知機能を呼び出さないと、QQで通知したり、クーポンを発行したりできませんか?それらすべてをロールバックします。それはあまりにも無理です。

あなたは一生懸命考えていて、イベント監視メカニズムを非同期的に切り離すことができることを学びました。このシナリオには適していませんか?それを行うだけで、コードのリファクタリングが始まります。

イベント監視ソリューション

ここでは、イベント監視メカニズムについては説明しません。Baiduには多くの概念があります。実際の例から始めて、このメカニズムの機能と使用時期を完全に理解できるようにします。

まず、支払いイベントクラスを定義しましょう

/**
 * 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;
    }
}

決済サービスクラスはこのように書かれています

/**
 * 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));
        }
    }
}

支払いが完了すると、イベントがリリースされます。ここでの要件は、支払い後にSMSでユーザーに通知し、注文変更ステータスを通知し、倉庫に出荷の準備を通知することです。公開されたイベントを受け取るために、それぞれ関連するクラスを作成します。

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

注文サービスは、支払いサービスから送信されたデータを監視すると、データの変更を開始します。

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

SMSサービスは、支払いイベントを監視します。支払いが成功すると、イベントを監視し、支払いが成功したというメッセージをユーザーに送信します。

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

同様に、倉庫が支払い成功イベントを監視すると、配達の準備を開始します。

テストイベントリリースメカニズム[つまり、支払いが成功したとき]

結果を表示

 

WeChat通知を追加する必要がある場合は、支払い成功イベントを監視するためにWeChatサービスクラスを作成するだけで済みます。同様に、QQ通知とクーポン配布、ポイント配布、およびその他の機能も同じ方法を使用します。

このように、支払い成功方法を変更する必要はありません。結局のところ、コア方法を変更することは依然として非常に危険です。

ここで私は2つの質問を投げます:

「「

1.イベントがリリースされた後にトランザクションが送信されておらず、反対側がそれをリッスンしている場合、データの不正確さとnullポインターの例外が発生する可能性があります。

2.イベントを発行する当事者がオペレーティングデータベースを持っている場合、イベントを監視する当事者もオペレーティングデータベースを持っています。イベントを監視している当事者がデータベースを操作しているときに例外がスローされた場合、イベントを公開している当事者はロールバックする必要がありますか?

これらの2つの問題に対するあなたの解決策は何ですか?

過去に推奨

QRコードをスキャンして、よりエキサイティングになります。または、WeChatLvshen_9を検索すると、返信してバックグラウンドで情報を取得できます

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终极版)

もう1つ:[マイベネフィット]をクリックして、さらに驚きを持ってください。

おすすめ

転載: blog.csdn.net/wujialv/article/details/108437884