成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SpringBoot+責任鏈實現接口動態編排!

開發 前端
項目中有一個 OpenApi 接口提供給客戶(上游系統)調用。這個接口中包含十幾個功能點,比如:入參校驗、系統配置校驗、基本數據入庫、核心數據入庫、發送給消息中心、發送給 MQ.....

一、背景

項目中有一個 OpenApi 接口提供給客戶(上游系統)調用。

這個接口中包含十幾個功能點,比如:入參校驗、系統配置校驗、基本數據入庫、核心數據入庫、發送給消息中心、發送給 MQ.....

不同的客戶對這個接口的要求也不同,有些功能不需要,有些需要添加特定功能。

二、思路

  • 基于以上背景,考慮把十幾個功能點進行拆分形成獨立的功能。因此使用責任鏈模式實現。
  • 創建一個抽象類(ComponentAbstract.java),每個拆分功能點繼承抽象類形成子類。
  • 子類創建時,需要在 @Component("1") 注解中設置類名,如果不設置咋使用默認的(小駝峰)名稱;關注公眾號:碼猿技術專欄,回復關鍵詞:1111 獲取阿里內部java性能調優手冊
  • 子類之間的數據通信使用自定義的上下文類(Contxt.java)子類中可以對上下文數據進行修改。(業務解耦)
  • 通過事先定義好的執行順序,通過 spring 的上下文 ApplicationContext 根據子類名稱循環獲取子類對象,執行抽象類中handlerRequest() 方法。
  • “事先定義好的執行順序”,可以保存到數據庫中項目啟動的時候加載到內存,或者直接維護到Redis中。我這邊直接使用接口進行演示:http://localhost:8082/test/chain?index=2,1,3,4

三、代碼

maven依賴,沒有特別的依賴fastjson用于測試時打印日志

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.76</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
</dependency>

ComponentAbstract.java 抽象類實現責任鏈的基礎

import com.liran.middle.liteflow.slot.Contxt;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;

/**
 * 組件抽象類
 */
@Slf4j
publicabstractclass ComponentAbstract {

    public void handlerRequest(Contxt contxt) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 執行子類業務邏輯
        this.doHandler(contxt);
        stopWatch.stop();
        long cost = stopWatch.getTotalTimeMillis();
        if (cost <= 10) {
            log.info("-----------監控統方法執行時間,執行 {} 方法, 用時優秀: {} ms -----------", getClass(), cost);
        } elseif (cost <= 50) {
            log.info("-----------監控統方法執行時間,執行 {} 方法, 用時一般: {} ms -----------", getClass(), cost);
        } elseif (cost <= 500) {
            log.info("-----------監控統方法執行時間,執行 {} 方法, 用時延遲: {} ms -----------", getClass(), cost);
        } elseif (cost <= 1000) {
            log.info("-----------監控統法執行時間,執行 {} 方法, 用時緩慢: {} ms -----------", getClass(), cost);
        } else {
            log.info("-----------監控方法執行時間,執行 {} 方法, 用時卡頓: {} ms -----------", getClass(), cost);
        }
    }
    abstract public void doHandler(Contxt contxt);
}

Test1.java 業務類1,繼承抽象類實現doHandler()方法,在@Component中設置類名1

import com.alibaba.fastjson.JSON;
import com.liran.middle.liteflow.slot.Contxt;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component("1")
@Slf4j
publicclass Test1 extends ComponentAbstract {
    @Override
    public void doHandler(Contxt contxt) {
        log.info("Test1-順序1-上下文內容為:{}", JSON.toJSONString(contxt));
        contxt.setName("Test1");
        contxt.setAge("Test1");
        contxt.setAdrss("Test1");
        contxt.setUserid("Test1");
    }
}

Test2.java 業務類2,繼承抽象類實現doHandler()方法,在@Component中設置類名2

import com.alibaba.fastjson.JSON;
import com.liran.middle.liteflow.slot.Contxt;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component("2")
@Slf4j
publicclass Test2 extends ComponentAbstract {

    @Override
    public void doHandler(Contxt contxt) {
        log.info("Test2-順序2-上下文內容為:{}", JSON.toJSONString(contxt));
        contxt.setName("Test2");
        contxt.setAge("Test2");
        contxt.setAdrss("Test2");
        contxt.setUserid("Test2");
    }
}

Test3.java 業務類3,繼承抽象類實現doHandler()方法,在@Component中設置類名3

import com.alibaba.fastjson.JSON;
import com.liran.middle.liteflow.slot.Contxt;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component("3")
@Slf4j
publicclass Test3 extends ComponentAbstract {
    @Override
    public void doHandler(Contxt contxt) {
        log.info("Test3-順序3-上下文內容為:{}", JSON.toJSONString(contxt));
        contxt.setName("Test3");
        contxt.setAge("Test3");
        contxt.setAdrss("Test3");
        contxt.setUserid("Test3");
    }
}

Test4.java 業務類4,繼承抽象類實現doHandler()方法,在@Component中設置類名4

import com.alibaba.fastjson.JSON;
import com.liran.middle.liteflow.slot.Contxt;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component("4")
@Slf4j
publicclass Test4 extends ComponentAbstract {

    @Override
    public void doHandler(Contxt contxt) {
        log.info("Test4-順序4-上下文內容為:{}", JSON.toJSONString(contxt));
        contxt.setName("Test4");
        contxt.setAge("Test4");
        contxt.setAdrss("Test4");
        contxt.setUserid("Test4");
    }
}

Contxt.java 業務上下文,用于每個子類(每個功能點)之間的數據通信。需要什么數據可以在此類中添加字段進行寫入,后面執行的類可以讀取。

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
publicclass Contxt {
    private String name;
    private String age;
    private String adrss;
    private String userid;
}

AopProxyUtils.java,spring 管理的上下文,用于根據類名獲取類實體。

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

@Component
publicclass AopProxyUtils implements ApplicationContextAware {

    privatestatic ApplicationContext applicationContext;

    /**
     * 實現ApplicationContextAware接口的setApplicationContext方法,
     * 用于注入ApplicationContext。
     */
    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        applicationContext = context;
    }

    /**
     * 獲取指定類的代理對象,適用于需要事務或其他AOP增強的場景。
     *
     * @param clazz 要獲取代理的對象的類
     * @param <T>   泛型標記
     * @return 代理對象實例
     */
    publicstatic <T> T getProxyBean(Class<T> clazz) {
        if (applicationContext == null) {
            thrownew IllegalStateException("ApplicationContext not initialized.");
        }
        return applicationContext.getBean(clazz);
    }

    public static Object getProxyBean(String name) {
        return applicationContext.getBean(name);
    }
}

LiteFlowController.java 用于測試,演示如何動態編排。調用接口http://localhost:8082/test/chain?index=2,1,3,4 傳入不同的index順序,業務邏輯中執行的順序也不同。

import com.alibaba.fastjson.JSON;
import com.liran.middle.liteflow.component.pattern.chain.ComponentAbstract;
import com.liran.middle.liteflow.slot.Contxt;
import com.liran.middle.liteflow.utils.AopProxyUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping(value = "/test")
@Slf4j
publicclass LiteFlowController {
    /**
     * 不使用框架,手動實現動態業務編排
     *
     * @param index 類名稱
     * @return
     */
    @GetMapping(value = "chain")
    public String pattern(@RequestParam String index) {
        Contxt contxt = new Contxt().builder()
                .age("初始化")
                .adrss("初始化")
                .name("初始化")
                .userid("初始化")
                .age("初始化")
                .build();
        String[] split = index.split(",");

        for (String className : split) {
            // 此處直接根據類名從 spring 管理的上下文中進行獲取。這里的類名是子類注解@Component("1")中自定義的,如果沒有定義的話,默認使用類名
            // 使用這種方式可以保證類名不重復。
            ComponentAbstract msgHandler = (ComponentAbstract) AopProxyUtils.getProxyBean(className);
            if (ObjectUtils.isNotEmpty(msgHandler)) {
                msgHandler.handlerRequest(contxt);
            } else {
                log.info("沒有找到對應的組件: {}", className);
            }
        }
        return JSON.toJSONString(contxt);
    }
}

四、注意

其實要實現這個功能使用 LiteFlow 框架最合適,文檔友好,接入簡單,功能強大。

LiteFlow 框架官網:https://liteflow.cc/pages/5816c5/

作者提供的代碼示例:https://gitee.com/bryan31/liteflow-example

我是因為公司內部對依賴包的引入有要求審核嚴格,所以自己實現了一個簡單版本的。

責任編輯:武曉燕 來源: 碼猿技術專欄
相關推薦

2022-12-28 08:08:57

2023-12-18 15:04:00

虛擬線程計算

2024-12-03 15:52:45

責任鏈Java

2012-03-28 13:28:56

Java設計模式

2022-11-01 08:46:20

責任鏈模式對象

2021-12-24 07:50:45

責任鏈模式設計

2022-07-01 08:36:44

流編排主流框架

2023-06-25 08:12:02

2021-07-14 10:08:30

責任鏈模式加工鏈

2024-06-04 13:11:52

Python行為設計模式開發

2025-05-13 04:15:00

2021-06-05 17:59:00

責任鏈模式設計

2010-04-01 09:10:03

PHP設計模式責任鏈模式

2021-06-09 07:15:15

責任鏈模式漲薪

2023-09-28 08:45:56

開源責任鏈模式

2021-05-25 09:00:52

責任鏈模式設計模式面試經歷

2024-01-30 13:15:00

設計模式責任鏈

2021-03-30 10:46:42

SpringBoot計數器漏桶算法

2020-11-17 09:32:57

設計模式責任鏈

2009-03-16 15:55:21

Java責任鏈模式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩欧美不卡 | 亚洲国产精选 | 新疆少妇videos高潮 | 在线日韩福利 | 国产资源一区二区三区 | 日本色高清 | 欧美综合在线观看 | a在线观看 | 精品久久久久久久久久久 | 国产一区二区精品自拍 | 亚洲国产成人精品女人久久久 | 成人午夜视频在线观看 | 国产日产精品一区二区三区四区 | 欧美a在线 | 国产精品美女久久久久久不卡 | 国产成人精品一区二区三区网站观看 | 久久精品国产精品青草 | 精品国产久 | 伦理二区| 午夜影院普通用户体验区 | 美国黄色毛片 | 国产亚洲区 | 国产96色在线 | 久在线 | 久久精品性视频 | 野狼在线社区2017入口 | 91久久夜色精品国产网站 | 欧美网站一区二区 | 中文字幕日韩一区 | 亚洲风情在线观看 | 香蕉婷婷 | 国产精品片aa在线观看 | 亚洲一区二区三区高清 | 国产一区二区毛片 | 欧美一区2区三区4区公司 | 亚洲欧洲一区 | 亚洲国产在 | 亚洲品质自拍视频网站 | 色综合天天综合网国产成人网 | 天天玩天天干天天操 | 日韩欧美中文字幕在线视频 |