欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring中OpenFeign的使用方法最佳實(shí)踐

 更新時間:2025年02月13日 08:28:26   作者:LileSily  
這篇文章主要介紹了Spring中OpenFeign使用的相關(guān)資料,OpenFeign是一個聲明式的WebService客戶端,簡化了微服務(wù)之間的調(diào)用,類似于Controller調(diào)用Service,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

1. RestTemplate存在的問題

觀察我們之前遠(yuǎn)程調(diào)用的代碼

public OrderInfo selectOrder(Integer id){
    OrderInfo orderInfo = orderMapper.selectOrderById(id);
    //把獲取到的服務(wù)URL拼接到遠(yuǎn)程調(diào)用的URL中
    String url = "http://product-service/product/select?id=" + orderInfo.getProductId();
    ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
    orderInfo.setProductInfo(productInfo);
    return orderInfo;
}

雖然說RestTemplate對HTTP封裝之后,已經(jīng)比直接使用HTTP Client方便很多,但是還是存在一些問題的.

  • 需要拼接URL,靈活性高,但是封裝臃腫,URL復(fù)雜的時候,容易出錯.
  • 代碼可讀性差,風(fēng)格不統(tǒng)一.

微服務(wù)之間的通行主要有兩種方式,一種是RPC,一種是HTTP.在SpringCloud中,默認(rèn)是使用HTTP進(jìn)行通信的,最常用的實(shí)現(xiàn)形式有兩種:

  • RestTemplate
  • OpenFeign

接下來我們就來詳細(xì)介紹一下OpenFeign.

2. OpenFeign介紹

OpenFeign是一個聲明式的Web Service客戶端.它讓微服務(wù)之間的調(diào)用變得更加簡單,類似與Controller調(diào)用Service,只需要創(chuàng)建一個接口,然后再添加注解就可以使用OpenFeign.

2.1 引入依賴

首先我們需要在服務(wù)調(diào)用方(order-service)中引入依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.2 添加注解

在order-service的啟動類添加注解,@EnableFeignClients,開啟OpenFeign的功能.

@SpringBootApplication
@EnableFeignClients
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class,args);
    }
}

2.3 編寫OpenFeign客戶端

在調(diào)用其他服務(wù)的客戶端之下,編寫API調(diào)用接口,基于SpringMVC的注解來聲明遠(yuǎn)程調(diào)用的信息.

@FeignClient(name = "product-service")
public interface ProductApi {
    @RequestMapping("/product/select")
    ProductInfo getProductInfo(@RequestParam("id")Integer id);
}

[注意]:在接口的參數(shù)前面必須使用@RequestParam加上所調(diào)用服務(wù)接口的對應(yīng)參數(shù),否則參數(shù)無法傳入,就相當(dāng)于在請求的后面加上了?參數(shù)=xxx.

也可以把該服務(wù)的接口的統(tǒng)一前綴(放在類上的@RequestMapping)統(tǒng)一放到FeignClient注解的Path參數(shù)中.

@FeignClient(name = "product-service",path = "/product")
public interface ProductApi {
    @RequestMapping("/select")
    ProductInfo getProductInfo(@RequestParam("id")Integer id);
}

@FeignClient注解作用在接口上,參數(shù)說明:

  • name/value: 指定OpenFeign的名稱,也就是被調(diào)用的微服務(wù)的名稱,用于服務(wù)發(fā)現(xiàn),Feign底層會使用SpringLoadBalance進(jìn)行負(fù)載均衡.
    當(dāng)然也可以使用URL屬性指定一個具體的URL.
  • Path: 定義當(dāng)前FeignClient的統(tǒng)一前綴,一般是被調(diào)用方Controller層的類注解.

2.4 遠(yuǎn)程調(diào)用

修改遠(yuǎn)程調(diào)用方法

@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ProductApi api;
    //設(shè)置原子類
    public OrderInfo selectOrder(Integer id){
        OrderInfo orderInfo = orderMapper.selectOrderById(id);
        //把獲取到的服務(wù)URL拼接到遠(yuǎn)程調(diào)用的URL中
        Integer productId = orderInfo.getProductId();
        ProductInfo productInfo = api.getProductInfo(productId);
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }
}

2.5 測試

啟動服務(wù).訪問接口,測試遠(yuǎn)程調(diào)用.

3. OpenFeign參數(shù)傳遞

3.1 傳遞單個參數(shù)

我們上面2.4的例子就是單個參數(shù)的調(diào)用.下面我們再來舉一個例子

  • 服務(wù)提供方product-service
@RestController
@RequestMapping("/product")
public class ProductController {
    @RequestMapping("/p1")
    public String p1(Integer id){
        return "接收到參數(shù)"+id;
    }
}
  • FeginClient
@FeignClient(value = "product-service")
public interface ProductApi {
    @RequestMapping("/product/p1")
    String p1(@RequestParam("id") Integer id);
}

和我們上面提到的一樣,@RequestParam是用來做參數(shù)綁定的,不能省略.

3. order-service

@RequestMapping("/order")
@RestController
public class OrderController {
    @Autowired
    private ProductApi api;
    @RequestMapping("/p1")
    public String p1(Integer id){
        return api.p1(id);
    }
}

遠(yuǎn)程測試調(diào)用:GET http://127.0.0.1:8080/order/p1?id=1

3.2 傳遞多個參數(shù)

使用多個@RequestParam進(jìn)行參數(shù)綁定即可

  • 服務(wù)提供方product-service
@RestController
@RequestMapping("/product")
public class ProductController {
    @RequestMapping("/p2")
    public String p2(Integer id1,Integer id2){
        return "接收到參數(shù)1:" + id1 + ",接收到參數(shù)2:" + id2;
    }
}
  • FeignClient
@FeignClient(value = "product-service")
public interface ProductApi {
    @RequestMapping("/product/p2")
    String p2(@RequestParam("id1") Integer p1,@RequestParam("id2") Integer p2);
}
  • 服務(wù)消費(fèi)方order-service
@RequestMapping("/order")
@RestController
public class OrderController {
    @Autowired
    private ProductApi api;
    @RequestMapping("/p2")
    public String p2(Integer p1,Integer p2){
        return api.p2(p1,p2);
    }
}

調(diào)用接口進(jìn)行測試:GET http://127.0.0.1:8080/order/p2?p1=1&p2=2

4.3 傳遞對象

  • 服務(wù)提供方product-service
@RequestMapping("/p3")
public String p3(ProductInfo productInfo){
    return "接收到對象:" + productInfo;
}
  • Feign
@RequestMapping("/product/p3")
String p3(@SpringQueryMap ProductInfo productInfo);

其中@SpringQueryMap注解表示的是:可以方便地將一個對象的屬性作為請求的查詢參數(shù)添加到請求的 URL中,避免了手動構(gòu)建查詢參數(shù)字符串(如json)的繁瑣過程.

3. order-service

@RequestMapping("/p3")
public String p3(ProductInfo productInfo){
    return api.p3(productInfo);
}

測試遠(yuǎn)程調(diào)用:GET http://127.0.0.1:8080/order/p3?id=5&productName=zhangsan

3.4 傳遞Json

和我們之前學(xué)習(xí)SpringBoot的時候一樣,同樣是使用@RequestBody注解進(jìn)行綁定.

注意由于數(shù)據(jù)在服務(wù)之間一直是按照J(rèn)son格式傳遞的,所以服務(wù)方,服務(wù)調(diào)用方,FeignClient的參數(shù)上都需要加上注解.

  • 服務(wù)提供方product-service
@RequestMapping("/p4")
public String p4(@RequestBody ProductInfo productInfo){
    return "接收到對象:" + productInfo;
}
  • FeignClient
@RequestMapping("/product/p4")
String p4(@RequestBody ProductInfo productInfo);
  • 服務(wù)消費(fèi)方order-service
@RequestMapping("/p4")
public String p4(@RequestBody ProductInfo productInfo){
    return api.p4(productInfo);
}

測試遠(yuǎn)程調(diào)用:http://127.0.0.1:8080/order/p4

4. 最佳實(shí)踐

通過觀察,我們也能看出來,Feign的客戶端與服務(wù)提供者的controller代碼非常相似.
Feign客戶端:

@FeignClient(value = "product-service")
public interface ProductApi {
    @RequestMapping("/product/p1")
    String p1(@RequestParam("id") Integer id);
}

服務(wù)提供方Controller

@RestController
@RequestMapping("/product")
public class ProductController {
    @RequestMapping("/p1")
    public String p1(Integer id){
        return "接收到參數(shù)"+id;
    }
}

有沒有一種方法可以簡化這種寫法呢?

4.1 Feign繼承方式

Feign支持繼承的方式,我們可以把一些常見的操作封裝到接口里.

我可以定義好一個接口,服務(wù)提供方實(shí)現(xiàn)這個接口,服務(wù)消費(fèi)方編寫Feign接口的時候,直接繼承這個接口.

接口可以放在一個公共的jar包中,供服務(wù)提供方和服務(wù)消費(fèi)方使用.

  • 新建一個模塊

  • 引入依賴
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
</dependencies>
  • 編寫接口
    復(fù)制ProductInfo類和ProductApi到product-api模塊中.把ProductApi改名為ProductInterface

  • 打jar包,并安裝到本地Maven倉庫


    點(diǎn)擊install.該模塊就會被安裝到本地的Maven倉庫.


    由于jar包中已經(jīng)有了ProductInfo類,所以我們就可以把product-service和order-service的ProductInfo類注掉了.
  • 服務(wù)提供方
    需要先在服務(wù)方中引入對應(yīng)模塊的依賴.
<dependency>
    <groupId>org.example</groupId>
    <artifactId>product-api</artifactId>
    <version>1.0-SNAPSHOT</version>
    <scope>compile</scope>
</dependency>

服務(wù)方product-service直接實(shí)現(xiàn)接口ProductInterface.

@RestController
@RequestMapping("/product")
public class ProductController implements ProductInterface {
    @Autowired
    private ProductService productService;
    @RequestMapping("/select")
    public ProductInfo getProductInfo(Integer id){
        return productService.selectById(id);
    }
    @RequestMapping("/p1")
    public String p1(Integer id){
        return "接收到參數(shù)"+id;
    }
    @RequestMapping("/p2")
    public String p2(Integer id1,Integer id2){
        return "接收到參數(shù)1:" + id1 + ",接收到參數(shù)2:" + id2;
    }
    @RequestMapping("/p3")
    public String p3(ProductInfo productInfo){
        return "接收到對象:" + productInfo;
    }
    @RequestMapping("/p4")
    public String p4(@RequestBody ProductInfo productInfo){
        return "接收到對象:" + productInfo;
    }
}
  • 服務(wù)消費(fèi)方
    同樣,首先先添加依賴.
    之后讓FeignClient繼承ProductInterface
@FeignClient(value = "product-service")
public interface ProductApi extends ProductInterface {

}

注意在上述步驟中,把ProductInfo類引入包的路徑全部改為之前打包的product-api模塊下ProductInfo類的路徑.

  • 測試接口
    http://127.0.0.1:8080/order/select?id=1

4.2 Feign抽取方式

官方推薦Feign的使用方式為繼承的方式,但是企業(yè)開發(fā)中,更多是把Feign接口抽取為?個獨(dú)立的模塊(做法和繼承相似,但理念不同).
操作方法:
將Feign的Client抽取為?個獨(dú)立的模塊,并把涉及到的實(shí)體類等都放在這個模塊中,打成?個Jar.服務(wù)消費(fèi)方只需要依賴該Jar包即可.這種方式在企業(yè)中比較常見,Jar包通常由服務(wù)提供方來實(shí)現(xiàn).
前4步和前面繼承的方式一樣.只不過接口ProductApi在復(fù)制到新模塊的時候不用修改名字

  • 服務(wù)消費(fèi)方使用product-api
    首先引入依賴,之后把該模塊中原有的ProductApi接口注掉.
<dependency>
	<groupId>org.example</groupId>
	<artifactId>product-api</artifactId>
	<version>1.0-SNAPSHOT</version>
</dependency>

之后指定掃描類
在啟動類中添加需要加載的Feign客戶端.

@SpringBootApplication
@EnableFeignClients(clients = ProductApi.class)
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class,args);
    }
}
  • 測試
    遠(yuǎn)程調(diào)用接口http://127.0.0.1:8080/order/select?id=1

總結(jié) 

到此這篇關(guān)于Spring中OpenFeign的使用方法的文章就介紹到這了,更多相關(guān)Spring OpenFeign的使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • dubbo整合springboot新手入門教程詳解

    dubbo整合springboot新手入門教程詳解

    這篇文章主要介紹了dubbo整合springboot新手入門詳解,當(dāng)一臺計(jì)算機(jī)的程序需要調(diào)用另一臺計(jì)算機(jī)代碼的時候,就涉及遠(yuǎn)程調(diào)用。此時dubbo就粉末登場了,需要的朋友可以參考下
    2019-07-07
  • JAVA中Integer值的范圍實(shí)例代碼

    JAVA中Integer值的范圍實(shí)例代碼

    這篇文章主要介紹了JAVA中Integer值的范圍實(shí)例代碼,需要的朋友可以參考下
    2017-09-09
  • Java關(guān)鍵字volatile詳析

    Java關(guān)鍵字volatile詳析

    這篇文章主要介紹了Java關(guān)鍵字volatile,volatile關(guān)鍵字可以說是Java虛擬機(jī)提供的最輕量級的同步機(jī)制,但對于為什么它只能保證可見性,不保證原子性,它又是如何禁用指令重排的,還有很多同學(xué)沒徹底理解,文章會讓大家牢掌握一個Java核心知識點(diǎn)
    2022-01-01
  • JDK13.0.1安裝與環(huán)境變量的配置教程圖文詳解(Win10平臺為例)

    JDK13.0.1安裝與環(huán)境變量的配置教程圖文詳解(Win10平臺為例)

    這篇文章主要介紹了JDK13.0.1安裝與環(huán)境變量的配置教程圖文詳解(Win10平臺為例),本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-01-01
  • Spring Boot集成Druid查看配置是否生效的方法

    Spring Boot集成Druid查看配置是否生效的方法

    本文主要介紹了Spring Boot集成Druid查看配置是否生效的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 使用@DS輕松解決動態(tài)數(shù)據(jù)源的問題

    使用@DS輕松解決動態(tài)數(shù)據(jù)源的問題

    這篇文章主要介紹了使用@DS輕松解決動態(tài)數(shù)據(jù)源的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 詳解如何保證Java本地緩存的一致性

    詳解如何保證Java本地緩存的一致性

    所謂的一致性是指在同時使用緩存和數(shù)據(jù)庫的場景下,要確保數(shù)據(jù)在緩存與數(shù)據(jù)庫中的更新操作保持同步,那么,怎么保證Java本地緩存的一致性?所以本文將給大家介紹了如何保證Java本地緩存的一致性,需要的朋友可以參考下
    2024-01-01
  • java 讀取excel文件轉(zhuǎn)換成json格式的實(shí)例代碼

    java 讀取excel文件轉(zhuǎn)換成json格式的實(shí)例代碼

    這篇文章主要介紹了 java 讀取excel文件轉(zhuǎn)換成json格式的實(shí)例代碼,需要的朋友可以參考下
    2018-04-04
  • Java 代碼檢查工具之PMD入門使用詳細(xì)教程

    Java 代碼檢查工具之PMD入門使用詳細(xì)教程

    這篇文章主要介紹了Java 代碼檢查工具之PMD入門使用詳細(xì)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Java中的值傳遞和引用傳遞實(shí)例介紹

    Java中的值傳遞和引用傳遞實(shí)例介紹

    java 中沒有引用傳遞,都是值傳遞的,可以通過傳遞副本修改對象的,副本交換,并不影響原引用
    2013-09-09

最新評論