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

強!Spring Boot 通過服務定位干掉if-else

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

環境:SpringBoot3.4.2

1. 簡介

相信在項目中都遇到過這樣的需求,根據不同的傳入類型調用同一個接口的不同實現類或服務處理邏輯。

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

圖片圖片

對于這樣的場景,我們通常會在調用客戶端中使用 if-else 語句。例如,如下代碼示例:

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

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

2.實戰案例

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 定義解析器接口

針對不同的文件類型,我們只需要定義對應的接口實現即可。

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

針對上面定義的3種文件類型,分別實現對應的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。我們接下來將直接通過beanName自動的查找對應解析器實現。

2.3 定義服務定位器接口

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

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

我們將直接通過參數ContentType來獲取對應的Parser具體實現。

2.4 配置ServiceLocatorFactoryBean

該類是我們的重點,我們就是通過它來定義具體的Parser實現。我們配置 ServiceLocatorFactoryBean 來使用 ParserFactory 作為服務定位器接口。ParserFactory 接口不需要具體的實現類。

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

如上配置后,ServiceLocatorFactoryBean底層會生成ParserFactory的代理類,對應的 InvocationHandler 實現會根據當前調用的方法參數(第一個參數)來獲取對應的beanName。

2.5 測試使用

接下來,在使用 Parser 時就無需關心去引入具體的實現了。通過上面的ServiceLocatorFactoryBean 可以直接根據類型獲取具有相應功能的 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);
  }
}

接下來,我們定義一個Runner進行測試

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

啟動服務后,控制臺輸出結果如下:

圖片

2.6 工作原理

如下圖是ServiceLocator服務定位的工作原理:

圖片

總結:服務定位器模式消除了客戶端對具體實現的依賴。以下是 Martin Fowler 文章中的一段話,它總結了該模式的核心思想:

“服務定位器的基本思想是擁有一個對象,該對象知道如何獲取應用程序可能需要的所有服務。”

責任編輯:武曉燕 來源: Springboot全家桶實戰案例
相關推薦

2020-10-22 09:20:22

SQLNoSQL 數據庫

2024-06-18 18:36:03

2020-04-09 08:29:50

編程語言事件驅動

2021-01-29 07:45:27

if-else代碼數據

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結構流程控制

2020-11-09 14:03:51

Spring BootMaven遷移

2013-03-06 10:28:57

ifJava

2021-04-20 08:02:08

業務數據用戶

2022-01-13 10:45:59

if-else代碼Java

2025-03-17 08:10:00

aviatorSpringJVM

2021-04-13 06:39:13

代碼重構code

2021-03-10 07:20:43

if-else靜態代碼

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語句

2020-07-09 08:59:52

if else模板Service
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品国产99| 久久青青 | 亚洲精品视频在线播放 | 激情国产 | 亚洲黄色在线 | 在线视频第一页 | 久久久久久久久淑女av国产精品 | 亚洲成人午夜电影 | 国产精品久久久久久久久久免费看 | 欧美专区在线 | 久久国产精品一区二区 | 国产伦一区二区三区 | 色99视频 | 91精品国产乱码久久久 | 国产精品乱码一区二区三区 | 久久久久成人精品 | 黑人精品欧美一区二区蜜桃 | 国产视频在线一区二区 | 久久三级影院 | 国产精品无码久久久久 | 羞羞视频在线免费 | 亚洲欧美日韩精品久久亚洲区 | 成人不卡 | 91高清视频在线 | 青青99 | 不卡一区二区三区四区 | av黄色免费在线观看 | 国产不卡视频在线 | 天天弄 | 91国自视频 | 日韩在线视频一区 | 一区二区高清在线观看 | 欧美在线播放一区 | 亚洲成人一区二区三区 | 日韩精品在线观看视频 | 国产精品成人av | 91精品在线看 | 久久国产精品-久久精品 | 一区二区三区视频免费观看 | 国产免费又黄又爽又刺激蜜月al | 欧美在线播放一区 |