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

原來使用 Spring 實現策略模式可以這么簡單!

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

 [[343796]]

 本文轉載自微信公眾號「Java極客技術」,作者鴨血粉絲 。轉載本文請聯系Java極客技術公眾號。

Hello,大家好,我是鴨血粉絲~

最近看同事的代碼時候,學到了個小技巧,在某些場景下非常挺有用的,這里分享一下給大家。

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

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

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

四個類的關系如下圖所示:

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

  1. // 首先通過 getBeanNamesForType 獲取 PayService 類型所有的 Bean 
  2. String[] names = ctx.getBeanNamesForType(PayService.class); 
  3. List<PayService> anotherPayService = Lists.newArrayList(); 
  4. for (String beanName : names) { 
  5.     anotherPayService.add(ctx.getBean(beanName, PayService.class)); 
  6. // 或者通過 getBeansOfType 獲取所有 PayService 類型 
  7. Map<String, PayService> beansOfType = ctx.getBeansOfType(PayService.class); 
  8. for (Map.Entry<String, PayService> entry : beansOfType.entrySet()) { 
  9.     anotherPayService.add(entry.getValue()); 

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

  1. @Autowired 
  2. List<PayService> payServices; 
  3.  
  4. @Autowired 
  5. PayService[] payServicesArray; 

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

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

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

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

假設我們這里發現,三者模式比較類似,只是部分傳參不一樣。

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

  1. public interface PayService { 
  2.     PayResult epay(PayRequest request); 

然后分別實現三個實現類,都繼承這個接口。

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

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

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

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

我們實現一個 RouteService,具體代碼邏輯如下:

  1. @Service 
  2. public class RouteService { 
  3.  
  4.     @Autowired 
  5.     Map<String, PayService> payServiceMap; 
  6.  
  7.     public PayResult epay(PayRequest payRequest) { 
  8.         PayService payService = payServiceMap.get(payRequest.getChannelNo()); 
  9.         return  payService.epay(payRequest); 
  10.     } 
  11.  

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

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

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

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

所以我們需要做個轉換,我們可以這么實現。

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

  1. public interface PayService { 
  2.  
  3.     PayResult epay(PayRequest request); 
  4.  
  5.     String channel(); 

具體舉個支付寶實現類的代碼,其他實現類實現類似。

  1. @Service("aliPayService"
  2. public class AliPayService implements PayService { 
  3.  
  4.     @Override 
  5.     public PayResult epay(PayRequest request) { 
  6.         // 業務邏輯 
  7.         return new PayResult(); 
  8.     } 
  9.     @Override 
  10.     public String channel() { 
  11.         return "00000001"
  12.     } 

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

  1. @Service 
  2. public class RouteService { 
  3.  
  4.     @Autowired 
  5.     Set<PayService> payServiceSet; 
  6.      
  7.     Map<String, PayService> payServiceMap; 
  8.  
  9.     public PayResult epay(PayRequest payRequest) { 
  10.         PayService payService = payServiceMap.get(payRequest.getChannelNo()); 
  11.         return  payService.epay(payRequest); 
  12.     } 
  13.  
  14.     @PostConstruct 
  15.     public void init() { 
  16.         for (PayService payService : payServiceSet) { 
  17.             payServiceMap = new HashMap<>(); 
  18.             payServiceMap.put(payService.channel(), payService); 
  19.         } 
  20.     } 

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

 

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2021-02-01 12:18:55

策略模式Spring

2022-06-17 07:32:39

策略模式SpringBoot

2014-10-08 15:00:50

SUSE操作系統云計算

2010-08-02 13:55:20

2016-03-21 11:09:52

Tableau/大數據

2021-04-19 05:42:51

Mmap文件系統

2023-11-01 14:49:07

2021-06-10 06:57:39

Redis存儲數據庫

2020-11-02 14:38:56

Java 深度學習模型

2022-12-06 17:30:04

2023-09-22 08:00:00

分布式鎖Redis

2020-09-24 06:44:54

HTTPS網站 HTTP

2020-11-27 10:34:01

HTTPHTTPS模型

2019-03-15 10:55:12

通信系統手機

2025-05-08 09:31:06

2014-11-25 15:02:01

客服系統

2025-03-20 12:33:36

2020-10-22 08:01:52

XMLJSON轉換

2018-10-28 17:54:00

分布式事務數據

2019-05-27 14:03:48

開發技能代碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美性精品 | 亚洲国产精品久久久久秋霞不卡 | 狠狠狠干 | 黄色一级大片在线免费看产 | 欧美精品成人 | 精品国产乱码久久久久久老虎 | 一区二区三区四区免费观看 | 国产午夜视频 | 日本激情视频在线播放 | 国产精品美女久久久久久不卡 | 日韩免费在线 | 免费中文字幕日韩欧美 | 国产福利资源在线 | 成人片免费看 | 欧美操操操 | 老司机久久 | 亚洲精品视| 久久伊人影院 | 伊人久久综合 | 综合一区二区三区 | 成人精品一区 | 男女网站免费观看 | 国产视频福利一区 | 午夜色播 | 欧美精品日韩精品 | 欧洲视频一区二区 | 视频一区中文字幕 | 国产精品视频久久久 | 亚洲成人在线视频播放 | 激情91| 毛片1| 国产精品久久久久久久久久久久久 | 欧美一区二区三区在线观看 | 国产资源在线视频 | 草久久 | 国产欧美一区二区三区久久人妖 | 日韩精品在线播放 | 国产成人一区二区三区 | 国产视频三区 | 国产综合视频 | 国产美女在线免费观看 |