溫馨提示×

溫馨提示×

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

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

如何使用Spring實現(xiàn)策略模式

發(fā)布時間:2022-02-25 10:30:02 來源:億速云 閱讀:311 作者:iii 欄目:開發(fā)技術

本篇內(nèi)容介紹了“如何使用Spring實現(xiàn)策略模式”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

Spring 中 @Autowired注解,大家應該不會陌生,用過 Spring 的肯定也離不開這個注解,通過這個注解可以幫我們自動注入我們想要的 Bean。

除了這個基本功能之外,@Autowired 還有更加強大的功能,還可以注入指定類型的數(shù)組,List/Set 集合,甚至還可以是 Map 對象。

比如說當前應用有一個支付接口 PayService,分別需要對接支付寶、微信支付、銀行卡,所以分別有三個不同實現(xiàn)類 AliPayService,WechatPayservice,BankCardPayService

如果此時我需要獲取當前系統(tǒng)類所有 PayService Bean,老的方式我們只能通過 BeanFactory或者 ApplicationContext 獲取。

// 首先通過 getBeanNamesForType 獲取 PayService 類型所有的 Bean
String[] names = ctx.getBeanNamesForType(PayService.class);
List anotherPayService = Lists.newArrayList();
for (String beanName : names) {
    anotherPayService.add(ctx.getBean(beanName, PayService.class));
}
// 或者通過 getBeansOfType 獲取所有 PayService 類型
Map beansOfType = ctx.getBeansOfType(PayService.class);
for (Map.Entry entry : beansOfType.entrySet()) {
    anotherPayService.add(entry.getValue());
}

但是現(xiàn)在我們可以不用這么麻煩了,我們可以直接使用 @Autowired 注入 PayService Bean 數(shù)組,或者 PayService List/Set 集合,甚至,我們還可以注入 PayService 的 Map 集合。

@Autowired
List payServices;


@Autowired
PayService[] payServicesArray;

知道了這個功能,當我們需要使用 Spring 實現(xiàn)策略模式就非常簡單。

可能有的小伙伴不太了解策略模式,沒關系,這類阿粉介紹一個業(yè)務場景,通過這個場景給大家介紹一下策略模式。

還是上面的例子,我們當前系統(tǒng)需要對接微信支付、支付寶、以及銀行卡支付。

當接到這個需求,我們首先需要拿到相應接口文檔,分析三者的共性。

假設我們這里發(fā)現(xiàn),三者模式比較類似,只是部分傳參不一樣。

所以我們根據(jù)三者的共性,抽象出一組公共的接口 PayService,

public interface PayService {
    PayResult epay(PayRequest request);
}

然后分別實現(xiàn)三個實現(xiàn)類,都繼承這個接口。

那么現(xiàn)在問題來了,由于存在三個實現(xiàn)類,如何選擇具體的實現(xiàn)類?

其實這個問題很好解決,請求參數(shù)傳入一個唯一標識,然后我們根據(jù)標識選擇相應的實現(xiàn)類。

比如說我們在請求類 PayRequest 搞個 channelNo 字段,這個代表相應支付渠道唯一標識,比如說支付寶為:00000001,微信支付為 00000002,銀行卡支付為 00000003。

接著我們需要把唯一標識與具體實現(xiàn)類一一映射起來,剛好我們可以使用 Map 存儲這種映射關系。

我們實現(xiàn)一個 RouteService,具體代碼邏輯如下:

@Service
public class RouteService {


    @Autowired
    Map payServiceMap;


    public PayResult epay(PayRequest payRequest) {
        PayService payService = payServiceMap.get(payRequest.getChannelNo());
        return  payService.epay(payRequest);
    }


}

我們在 RouteService 自動注入 PayService 所有相關 Bean,然后使用唯一標識查找實現(xiàn)類。

這樣我們對外就屏蔽了支付渠道的差異,其他服務類只要調(diào)用 RouteService 即可。

但是這樣實現(xiàn)還是有點小問題,由于我們唯一標識為一串數(shù)字,如果像我們上面直接使用 @Autowired注入 Map,這就需要我們實現(xiàn)類的 Bean 名字為 00000001 這些。

但是這樣命名不是很優(yōu)雅,這樣會讓后來同學很難看懂,不好維護。

所以我們需要做個轉(zhuǎn)換,我們可以這么實現(xiàn)。

首先我們改造一下 PayService 這個接口,增加一個方法,每個具體實現(xiàn)類通過這個方法返回其唯一標識。

public interface PayService {


    PayResult epay(PayRequest request);


    String channel();
}

具體舉個支付寶實現(xiàn)類的代碼,其他實現(xiàn)類實現(xiàn)類似。

@Service("aliPayService")
public class AliPayService implements PayService {


    @Override
    public PayResult epay(PayRequest request) {
        // 業(yè)務邏輯
        return new PayResult();
    }
    @Override
    public String channel() {
        return "00000001";
    }
}

最后我們改造一下 RouteService,具體邏輯如下:

@Service
public class RouteService {


    @Autowired
    Set payServiceSet;

    
    Map payServiceMap;


    public PayResult epay(PayRequest payRequest) {
        PayService payService = payServiceMap.get(payRequest.getChannelNo());
        return  payService.epay(payRequest);
    }


    @PostConstruct
    public void init() {
        for (PayService payService : payServiceSet) {
            payServiceMap = new HashMap();
            payServiceMap.put(payService.channel(), payService);
        }
    }
}

上面代碼首先通過自動注入 PayService 一個集合,然后我們再將其轉(zhuǎn)為一個 Map,這樣內(nèi)部存儲剛好是唯一標識與實現(xiàn)類的映射了。

“如何使用Spring實現(xiàn)策略模式”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)

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

AI