最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot如何通過(guò)不同的策略動(dòng)態(tài)調(diào)用不同的實(shí)現(xiàn)類

 更新時(shí)間:2022年02月26日 10:27:39   作者:SunAlwaysOnline  
這篇文章主要介紹了springboot如何通過(guò)不同的策略動(dòng)態(tài)調(diào)用不同的實(shí)現(xiàn)類,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

通過(guò)不同的策略動(dòng)態(tài)調(diào)用不同的實(shí)現(xiàn)類

經(jīng)常遇到這樣的一個(gè)需求,前端傳的實(shí)體類型相同,后端需要根據(jù)實(shí)體類中的某一個(gè)字符串,動(dòng)態(tài)地調(diào)用某一個(gè)類的方法。

在SpringBoot中,我們可以理解成,一個(gè)Controller接口對(duì)應(yīng)多個(gè)ServiceImpl,使用這種方式,如果后期需要添加一個(gè)功能,僅僅創(chuàng)建一個(gè)ServiceImpl就可以滿足需求,而不用再額外創(chuàng)建一個(gè)Controller接口。

現(xiàn)在假設(shè)一個(gè)情景,前端傳入不同的用戶類型,后端返回該用戶的任務(wù)。

你可能問(wèn)我,為什么不直接把(用戶類型,用戶任務(wù))存入數(shù)據(jù)庫(kù)?

現(xiàn)在只是一個(gè)簡(jiǎn)單的場(chǎng)景而已,實(shí)際中更為復(fù)雜,無(wú)法直接存入數(shù)據(jù)庫(kù)。

代碼演示

我們先定義一個(gè)接口

public interface UserService { 
    //返回用戶的主要任務(wù)
    String task();
}

兩個(gè)實(shí)現(xiàn)類

@Service("student")
public class StudentServiceImpl implements UserService {
? ? @Override
? ? public String task() {
? ? ? ? return "學(xué)習(xí)";
? ? }
}
@Service("teacher")
public class TeacherServiceImpl implements UserService {
? ? @Override
? ? public String task() {
? ? ? ? return "教書(shū)";
? ? }
}

實(shí)現(xiàn)動(dòng)態(tài)調(diào)用的核心類

@Service
public class UserContext {?
? ? @Autowired
? ? Map<String, UserService> userMap;
?
? ? public UserService getUserService(String type) {
? ? ? ? return userMap.get(type);
? ? }
}

Spring會(huì)自動(dòng)地將形如(@Service后面的名稱,實(shí)現(xiàn)該接口的類)注入到該userMap中

在啟動(dòng)后,userMap中就存在兩個(gè)元素,("student",StudentServiceImpl)與("teacher",TeacherServiceImpl)

getUserService方法返回userMap中key=type的UserService對(duì)象

實(shí)體類

public class User { 
    private String type; 
    private String task; 
    public String getType() {
        return type;
    }
 
    public void setType(String type) {
        this.type = type;
    }
 
    public String getTask() {
        return task;
    }
 
    public void setTask(String task) {
        this.task = task;
    }
}

Controller層接口

@RestController
@RequestMapping("/user")
public class UserController { 
    @Autowired
    UserContext userContext;
 
    @PostMapping("/getTask")
    public String getTask(@RequestBody User user) {
        UserService userService = userContext.getUserService(user.getType());
        return userService.task();
    }
}

測(cè)試樣例:

可能用到的場(chǎng)景舉例

關(guān)于庫(kù)存的儀表盤(pán)統(tǒng)計(jì)

前端傳入?yún)^(qū)域id,倉(cāng)庫(kù)id,物品id等信息

后端依據(jù)參數(shù)動(dòng)態(tài)地選擇某一個(gè)物品實(shí)現(xiàn)類,最后返回統(tǒng)計(jì)的信息。

這里有幾個(gè)問(wèn)題,為什么不一次性將所有物品id傳入,一次性獲取所有物品的庫(kù)存?

一次性傳入,可能后端處理時(shí)間邊長(zhǎng),失敗率也高,一旦失敗,整個(gè)儀表盤(pán)沒(méi)有任何數(shù)據(jù)。而且后期可能面臨的一個(gè)需求,不同的物品,需要有不同的接口刷新速度,暢銷的物品接口調(diào)用頻率快。所以可能需要將物品分組,一個(gè)小組是同一種類型,使用一個(gè)實(shí)現(xiàn)類。

比如,這里有100種物品,按類型或者其他屬性分成了10組,每個(gè)組之間,有一個(gè)不同的屬性groupId,但10組共用一個(gè)接口,進(jìn)入接口后,再進(jìn)入10個(gè)不同的實(shí)現(xiàn)類,在實(shí)現(xiàn)類中調(diào)用具體的計(jì)算邏輯。

spring中動(dòng)態(tài)選擇實(shí)現(xiàn)類

在spring中當(dāng)一個(gè)接口有多個(gè)實(shí)現(xiàn)類的時(shí)候,通過(guò)創(chuàng)建簡(jiǎn)單工廠類,根據(jù)傳入的不同的參數(shù)獲取不同的接口實(shí)現(xiàn)類。

public interface ExecuteService {?? ?
?? ?ExecuteEnum getCode();
? ? // 業(yè)務(wù)方法
? ? void execute();
}
@Service
public class FirstExecuteServiceImpl implements ExecuteService {?? ?
?? ?@Override
?? ?public ExecuteEnum getCode() {
?? ??? ?return ExecuteEnum.FIRST;
?? ?}
?? ?
?? ?public void execute() {
?? ? ? ?System.out.println("11111111111");
?? ?}
}
@Service
public class SecondExecuteServiceImpl implements ExecuteService {?? ?
?? ?@Override
?? ?public ExecuteEnum getCode() {
?? ??? ?return ExecuteEnum.SECOND;
?? ?}
?? ?
?? ?public void execute() {
?? ? ? ?System.out.println("222222222");
?? ?}
}
?? ?public enum ExecuteEnum {
?? ??? ?FIRST,
?? ??? ?SECOND,;
?? ?}

方案一

@Component
public class ExecuteServiceFactory implements ApplicationContextAware {
?? ?
?? ?private final static Map<ExecuteEnum, ExecuteService> EXECUTE_SERVICES = new HashMap<>();
?? ?@Override
?? ?public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
?? ??? ?Map<String, ExecuteService> types = applicationContext.getBeansOfType(ExecuteService.class);
?? ??? ?types.values().forEach(e -> EXECUTE_SERVICES.putIfAbsent(e.getCode(), e));
?? ?}?? ?
}

方案二

@Component
public class ExecuteServiceFactory implements InitializingBean {
? ? @Autowired
? ? private List<ExecuteService> executeServices;
? ? public final static Map<ExecuteEnum, ExecuteService> EXECUTE_SERVICES = new HashMap<>();
? ? @Override
? ? public void afterPropertiesSet() throws Exception {
? ? ? ? executeServices.forEach(l -> EXECUTE_SERVICES.putIfAbsent(l.getCode(), l));
? ? }
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解Java中wait和sleep的區(qū)別

    詳解Java中wait和sleep的區(qū)別

    這篇文章主要介紹了Java中wait和sleep的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Mybatis批量插入并返回主鍵id的方法

    Mybatis批量插入并返回主鍵id的方法

    本文主要介紹了Mybatis批量插入并返回主鍵id的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • mybatis的映射xml中動(dòng)態(tài)設(shè)置orderby方式

    mybatis的映射xml中動(dòng)態(tài)設(shè)置orderby方式

    這篇文章主要介紹了mybatis的映射xml中動(dòng)態(tài)設(shè)置orderby方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java中Sentinel框架詳解

    Java中Sentinel框架詳解

    Sentinel是一個(gè)高可用、高擴(kuò)展、高穩(wěn)定性的開(kāi)源流量控制和熔斷降級(jí)框架,可以在分布式系統(tǒng)中實(shí)現(xiàn)實(shí)時(shí)的流量控制,防止系統(tǒng)因流量過(guò)大導(dǎo)致系統(tǒng)崩潰和服務(wù)降級(jí),Sentinel面向所有的Java應(yīng)用,本文就給大家詳細(xì)介紹一下Java中Sentinel框架,需要的朋友可以參考下
    2023-06-06
  • springboot 場(chǎng)景啟動(dòng)器使用解析

    springboot 場(chǎng)景啟動(dòng)器使用解析

    這篇文章主要介紹了springboot 場(chǎng)景啟動(dòng)器使用解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 使用idea和gradle編譯spring5源碼的方法步驟

    使用idea和gradle編譯spring5源碼的方法步驟

    這篇文章主要介紹了詳解使用idea和gradle編譯spring5源碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Spring整合Mybatis詳細(xì)步驟

    Spring整合Mybatis詳細(xì)步驟

    今天帶大家來(lái)學(xué)習(xí)Spring怎么整合Mybatis,文中有非常詳細(xì)的代碼示例及介紹,對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • Java實(shí)現(xiàn)Floyd算法的示例代碼

    Java實(shí)現(xiàn)Floyd算法的示例代碼

    Floyd算法又稱為插點(diǎn)法,是一種利用動(dòng)態(tài)規(guī)劃的思想尋找給定的加權(quán)圖中多源點(diǎn)之間最短路徑的算法。本文將用Java語(yǔ)言實(shí)現(xiàn)Floyd算法,需要的可以參考一下
    2022-07-07
  • JDK源碼之PriorityQueue解析

    JDK源碼之PriorityQueue解析

    這篇文章主要為大家詳細(xì)介紹了JDK源碼之PriorityQueue,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Java實(shí)戰(zhàn)之基于I/O流設(shè)計(jì)的圖書(shū)管理系統(tǒng)

    Java實(shí)戰(zhàn)之基于I/O流設(shè)計(jì)的圖書(shū)管理系統(tǒng)

    這篇文章主要介紹了Java實(shí)戰(zhàn)之基于I/O流設(shè)計(jì)的圖書(shū)館管理系統(tǒng),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04

最新評(píng)論

灵璧县| 遂宁市| 西丰县| 玉环县| 浑源县| 青神县| 辽中县| 前郭尔| 兴化市| 呈贡县| 永吉县| 太和县| 资兴市| 大姚县| 嘉定区| 上栗县| 涡阳县| 永新县| 法库县| 泽州县| 邮箱| 盘锦市| 祁门县| 长岛县| 昌图县| 晋江市| 灵丘县| 桃园县| 泸州市| 通榆县| 福海县| 广安市| 如东县| 安宁市| 陈巴尔虎旗| 抚宁县| 云林县| 仙游县| 施秉县| 蚌埠市| 河北区|