溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

springboot怎么通過不同的策略動態(tài)調用不同的實現(xiàn)類

發(fā)布時間:2022-02-28 09:24:18 來源:億速云 閱讀:452 作者:iii 欄目:開發(fā)技術

這篇“springboot怎么通過不同的策略動態(tài)調用不同的實現(xiàn)類”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“springboot怎么通過不同的策略動態(tài)調用不同的實現(xiàn)類”文章吧。

通過不同的策略動態(tài)調用不同的實現(xiàn)類

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

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

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

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

現(xiàn)在只是一個簡單的場景而已,實際中更為復雜,無法直接存入數(shù)據(jù)庫。

代碼演示

我們先定義一個接口

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

兩個實現(xiàn)類

@Service("student")
public class StudentServiceImpl implements UserService {
    @Override
    public String task() {
        return "學習";
    }
}
@Service("teacher")
public class TeacherServiceImpl implements UserService {
    @Override
    public String task() {
        return "教書";
    }
}

實現(xiàn)動態(tài)調用的核心類

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

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

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

getUserService方法返回userMap中key=type的UserService對象

實體類

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

測試樣例:

springboot怎么通過不同的策略動態(tài)調用不同的實現(xiàn)類

springboot怎么通過不同的策略動態(tài)調用不同的實現(xiàn)類

可能用到的場景舉例

關于庫存的儀表盤統(tǒng)計

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

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

這里有幾個問題,為什么不一次性將所有物品id傳入,一次性獲取所有物品的庫存?

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

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

spring中動態(tài)選擇實現(xiàn)類

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

public interface ExecuteService {    
    ExecuteEnum getCode();
    // 業(yè)務方法
    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));
    }
}

以上就是關于“springboot怎么通過不同的策略動態(tài)調用不同的實現(xiàn)類”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI