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

強(qiáng)!Spring Boot 通過(guò)服務(wù)定位干掉if-else

開發(fā) 前端
需要不同的解析器來(lái)處理不同的文件類型。例如,XML 文件由 XML 解析器處理,而 JSON 文件則由 JSON 解析器處理。

環(huán)境:SpringBoot3.4.2

1. 簡(jiǎn)介

相信在項(xiàng)目中都遇到過(guò)這樣的需求,根據(jù)不同的傳入類型調(diào)用同一個(gè)接口的不同實(shí)現(xiàn)類或服務(wù)處理邏輯。

例如,需要不同的解析器來(lái)處理不同的文件類型。例如,XML 文件由 XML 解析器處理,而 JSON 文件則由 JSON 解析器處理。

圖片圖片

對(duì)于這樣的場(chǎng)景,我們通常會(huì)在調(diào)用客戶端中使用 if-else 語(yǔ)句。例如,如下代碼示例:

public void processFile(String contentType, String filePath) {
  if ("json".equalsIgnoreCase(contentType)) {
    // ..
  } else if ("xml".equalsIgnoreCase(contentType)) {
    // ...
  } else if ("csv".equalsIgnoreCase(contentType)) {
    // ...
  } else {
    // ...
  }
}

本篇文章將介紹另外一種使用 服務(wù)定位器模式(Service Locator Pattern)的方法。其核心思想是面向接口編程,幫助我們消除緊密耦合的實(shí)現(xiàn),并減輕客戶端對(duì)具體實(shí)現(xiàn)類的依賴。

2.實(shí)戰(zhàn)案例

2.1 定義枚舉

在該枚舉類中,我們定義了將要處理的文件類型。

public enum ContentType {
  JSON(TypeConstants.JSON_PARSER), 
  XML(TypeConstants.XML_PARSER), 
  CSV(TypeConstants.CSV_PARSER);


  private final String parserName;
  ContentType(String parserName) {
    this.parserName = parserName;
  }
  @Override
  public String toString() {
    return this.parserName;
  }
  public interface TypeConstants {
    String CSV_PARSER = "csvParser";
    String JSON_PARSER = "jsonParser";
    String XML_PARSER = "xmlParser";
  }
}

2.2 定義解析器接口

針對(duì)不同的文件類型,我們只需要定義對(duì)應(yīng)的接口實(shí)現(xiàn)即可。

public interface Parser {
  Map<String, Object> parse(Reader r);
}

針對(duì)上面定義的3種文件類型,分別實(shí)現(xiàn)對(duì)應(yīng)的Parser。

@Component(TypeConstants.CSV_PARSER)
public class CSVParser implements Parser {
  @Override
  public Map<String, Object> parse(Reader r) {
    return Map.of("csv", "csv文件解析成功") ;
  } 
}
@Component(TypeConstants.JSON_PARSER)
public class JSONParser implements Parser {
  @Override
  public Map<String, Object> parse(Reader r) {
    return Map.of("json", "json文件解析成功") ;
  }
}
@Component(TypeConstants.XML_PARSER)
public class XMLParser implements Parser {
  @Override
  public Map<String, Object> parse(Reader r) {
    return Map.of("xml", "xml文件解析成功") ;
  }
}

注意,我們這里的beanName。我們接下來(lái)將直接通過(guò)beanName自動(dòng)的查找對(duì)應(yīng)解析器實(shí)現(xiàn)。

2.3 定義服務(wù)定位器接口

該接口中只有一個(gè)方法 getParser,該方法接受一個(gè)內(nèi)容類型(contentType)作為參數(shù),并返回 Parser 接口。

public interface ParserFactory {
  Parser getParser(ContentType contentType);
}

我們將直接通過(guò)參數(shù)ContentType來(lái)獲取對(duì)應(yīng)的Parser具體實(shí)現(xiàn)。

2.4 配置ServiceLocatorFactoryBean

該類是我們的重點(diǎn),我們就是通過(guò)它來(lái)定義具體的Parser實(shí)現(xiàn)。我們配置 ServiceLocatorFactoryBean 來(lái)使用 ParserFactory 作為服務(wù)定位器接口。ParserFactory 接口不需要具體的實(shí)現(xiàn)類。

@Configuration
public class ParserConfig {
  @Bean("parserFactory")
  ServiceLocatorFactoryBean serviceLocatorFactoryBean() {
    ServiceLocatorFactoryBean factoryBean = new ServiceLocatorFactoryBean();
    factoryBean.setServiceLocatorInterface(ParserFactory.class);
    return factoryBean;
  }
}

如上配置后,ServiceLocatorFactoryBean底層會(huì)生成ParserFactory的代理類,對(duì)應(yīng)的 InvocationHandler 實(shí)現(xiàn)會(huì)根據(jù)當(dāng)前調(diào)用的方法參數(shù)(第一個(gè)參數(shù))來(lái)獲取對(duì)應(yīng)的beanName。

2.5 測(cè)試使用

接下來(lái),在使用 Parser 時(shí)就無(wú)需關(guān)心去引入具體的實(shí)現(xiàn)了。通過(guò)上面的ServiceLocatorFactoryBean 可以直接根據(jù)類型獲取具有相應(yīng)功能的 Parser 接口。

@Service
public class ParserService {
  private final ParserFactory parserFactory;
  public ParserService(ParserFactory parserFactory) {
    this.parserFactory = parserFactory;
  }
  public Map<String, Object> getData(ContentType contentType) {
    Parser parser = parserFactory.getParser(contentType) ;
    InputStreamReader reader = null ;
    return parser.parse(reader);
  }
}

接下來(lái),我們定義一個(gè)Runner進(jìn)行測(cè)試

@Component
public class ParserRunner implements CommandLineRunner {
  private final ParserService parserService ;
  public ParserRunner(ParserService parserService) {
    this.parserService = parserService;
  }
  @Override
  public void run(String... args) throws Exception {
    Map<String, Object> data = this.parserService.getData(ContentType.CSV) ;
    System.err.println(data) ;
    data = this.parserService.getData(ContentType.JSON) ;
    System.err.println(data) ;
    data = this.parserService.getData(ContentType.XML) ;
    System.err.println(data) ;
  }
}

啟動(dòng)服務(wù)后,控制臺(tái)輸出結(jié)果如下:

圖片

2.6 工作原理

如下圖是ServiceLocator服務(wù)定位的工作原理:

圖片

總結(jié):服務(wù)定位器模式消除了客戶端對(duì)具體實(shí)現(xiàn)的依賴。以下是 Martin Fowler 文章中的一段話,它總結(jié)了該模式的核心思想:

“服務(wù)定位器的基本思想是擁有一個(gè)對(duì)象,該對(duì)象知道如何獲取應(yīng)用程序可能需要的所有服務(wù)。”

責(zé)任編輯:武曉燕 來(lái)源: Springboot全家桶實(shí)戰(zhàn)案例
相關(guān)推薦

2020-10-22 09:20:22

SQLNoSQL 數(shù)據(jù)庫(kù)

2024-06-18 18:36:03

2020-04-09 08:29:50

編程語(yǔ)言事件驅(qū)動(dòng)

2021-01-29 07:45:27

if-else代碼數(shù)據(jù)

2019-04-25 14:25:24

Spring Bootif elseJava

2022-07-11 08:16:55

策略模式if-else

2025-03-12 14:09:56

2023-06-02 07:30:24

If-else結(jié)構(gòu)流程控制

2020-11-09 14:03:51

Spring BootMaven遷移

2013-03-06 10:28:57

ifJava

2021-04-20 08:02:08

業(yè)務(wù)數(shù)據(jù)用戶

2022-01-13 10:45:59

if-else代碼Java

2025-03-17 08:10:00

aviatorSpringJVM

2021-04-13 06:39:13

代碼重構(gòu)code

2021-03-10 07:20:43

if-else靜態(tài)代碼

2020-12-15 09:31:58

CTOif-else代碼

2020-05-13 14:15:25

if-else代碼前端

2021-11-04 08:53:00

if-else代碼Java

2025-04-24 08:40:00

JavaScript代碼return語(yǔ)句

2020-07-09 08:59:52

if else模板Service
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 黄色免费观看 | 欧美一区二区在线看 | 精品国产一区二区国模嫣然 | 日本免费黄色一级片 | 九九免费视频 | 爱爱无遮挡 | 欧美日韩电影免费观看 | 国产91在线播放 | 在线视频国产一区 | 久久久国产精品 | www.99精品 | 国产日产精品一区二区三区四区 | 三级视频在线观看 | 久久五月婷 | 久久久.com| 俺去俺来也www色官网cms | 成人一区二区电影 | 九九伦理片| 亚洲精品一区二区三区免 | 久久视频免费看 | 紧缚调教一区二区三区视频 | 一级欧美 | 亚洲欧美日韩一区 | 国产精品欧美一区二区三区不卡 | 美女精品一区 | 免费三级网站 | 91麻豆精品国产91久久久久久 | 在线播放国产一区二区三区 | 久久精品国产一区 | 国产精品一区久久久久 | 色综合99 | 欧美狠狠操| 欧美成人自拍视频 | 黄色大片视频 | 欧美日韩精品一区二区三区蜜桃 | 免费看国产a | 亚洲人成人一区二区在线观看 | 国产成人免费视频网站视频社区 | 久久高清 | 九九久久久 | 国产一区二区三区久久久久久久久 |