SpringCloud中的OpenFeign調(diào)用解讀
基本介紹
引進
如果我們利用RestTemplate發(fā)起遠程調(diào)用的代碼時會存在一些問題比如:
•代碼可讀性差,編程體驗不統(tǒng)一
•參數(shù)復雜URL難以維護
String url="http://teacherservice/getTeacher"; Teacher teacher = restTemplate.getForObject(url, Teacher.class);
OpenFeign概述
OpenFeign是一個顯示聲明式的WebService客戶端。使用OpenFeign能讓編寫Web Service客戶端更加簡單。使用時只需定義服務接口,然后在上面添加注解。OpenFeign也支持可拔插式的編碼和解碼器。spring cloud對feign進行了封裝,使其支持MVC注解和HttpMessageConverts。和eureka(服務注冊中心)和ribbon組合可以實現(xiàn)負載均衡。
在Spring Cloud中使用OpenFeign,可以做到使用HTTP請求訪問遠程服務,就像調(diào)用本地方法一樣的,開發(fā)者完全感知不到這是在調(diào)用遠程方法,更感知不到在訪問HTTP請求,非常的方便。
cloud官網(wǎng)介紹Feign:Spring Cloud OpenFeign
OpenFeign源碼:GitHub - OpenFeign/feign: Feign makes writing java http clients easier
OpenFeign作用
- OpenFeign的設計宗旨式簡化Java Http客戶端的開發(fā)。Feign在restTemplate的基礎上做了進一步的封裝,由其來幫助我們定義和實現(xiàn)依賴服務接口的定義。在OpenFeign的協(xié)助下,我們只需創(chuàng)建一個接口并使用注解的方式進行配置(類似于Dao接口上面的Mapper注解)即可完成對服務提供方的接口綁定,大大簡化了Spring cloud Ribbon的開發(fā),自動封裝服務調(diào)用客戶端的開發(fā)量。
- OpenFeign集成了Ribbon,利用ribbon維護了服務列表,并且通過ribbon實現(xiàn)了客戶端的負載均衡。與ribbon不同的是,通過OpenFeign只需要定義服務綁定接口且以申明式的方法,優(yōu)雅而簡單的實現(xiàn)了服務調(diào)用。 @FeignClient
@FeignClient
實現(xiàn)的是聲明式的、模塊化的Http客戶端,可以讓我們對其他服務接口的訪問更邊界就像是controller和service之間的調(diào)用一樣。
@FeignClient屬性如下:
- name:指定該類的容器名稱,類似于@Service(容器名稱)
- url: url一般用于調(diào)試,可以手動指定@FeignClient調(diào)用的地址
- decode404:當發(fā)生http 404錯誤時,如果該字段位true,會調(diào)用decoder進行解碼,否則拋出FeignException
- configuration: Feign配置類,可以自定義Feign的Encoder、Decoder、LogLevel、Contract
- fallback: 定義容錯的處理類,當調(diào)用遠程接口失敗或超時時,會調(diào)用對應接口的容錯邏輯,fallback指定的類必須實現(xiàn)@FeignClient標記的接口
- fallbackFactory: 工廠類,用于生成fallback類示例,通過這個屬性我們可以實現(xiàn)每個接口通用的容錯邏輯,減少重復的代碼
- path: 定義當前FeignClient的統(tǒng)一前綴,當我們項目中配置了server.context-path,server.servlet-path時使用
@FeignClient(name="teacherservice")
public interface TeacherServiceFeign {
@GetMapping("/getTeacher/{id}")
Teacher getInfo(@PathVariable("id") String id);
}@EnableFeignClients
在的啟動類添加? @EnableFeignClients注解開啟Feign的功能
用注解@EnableFeignClients啟用feign客戶端;掃描和注冊feign客戶端bean定義
@EnableFeignClients注解中的basePackges屬性中是一個數(shù)組,可以填寫多個值,其主要作用是指定當前模塊中需要用到那些地址下的feign接口,起到一個discovery發(fā)現(xiàn)feign接口的作用。
Java代碼實戰(zhàn)
實戰(zhàn)架構(gòu)

倆個為倆個不同的端口的service端,客戶端向8002端口的studentservice發(fā)送一個請求(/getInfo/{id})以后,8002端口的studentservice需要往teacherservice發(fā)送一個請求(/getTeacher/{id})返回數(shù)據(jù)。
父工程pom文件
統(tǒng)一管理版本信息
<groupId>org.example</groupId>
<artifactId>eurek-test</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>eurek-serve</module>
<module>student-service</module>
<module>teacher-service</module>
</modules>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR10</spring-cloud.version>
<mysql.version>5.1.47</mysql.version>
<mybatis.version>2.1.1</mybatis.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- springCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--nacos的管理依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>teacher-service服務
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- nacos客戶端依賴包 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>啟動類
@SpringBootApplication
public class TeacherApplication {
public static void main(String[] args) {
SpringApplication.run(TeacherApplication.class,args);
}
}yml配置文件
server:
port: 8002
spring:
application:
name: teacherservice
cloud:
nacos:
server-addr: localhost:8848Teacher類
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher implements Serializable {
private String name;
private String sex;
}TeachertController
@RestController
public class TeacherController {
@GetMapping("/getTeacher/{id}")
public Teacher getInfo(@PathVariable("id") String id){
return new Teacher("張三-"+id,"男");
}
}student-service服務
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- nacos客戶端依賴包 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>yml配置文件
server:
port: 8002
spring:
application:
name: studentservice
cloud:
nacos:
server-addr: localhost:8848啟動類
@SpringBootApplication
@EnableFeignClients
public class StudentApplication {
public static void main(String[] args) {
SpringApplication.run(StudentApplication.class,args);
}
}Teacher類
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher implements Serializable {
private String name;
private String sex;
}TeacherServiceFeign ?
@FeignClient("teacherservice")
public interface TeacherServiceFeign {
@GetMapping("/getTeacher/{id}")
Teacher getInfo(@PathVariable("id") String id);
}個客戶端主要是基于SpringMVC的注解來聲明遠程調(diào)用的信息,比如:
- 服務名稱:teacherservice
- 請求方式:GET
- 請求路徑:/getTeacher/{id}
- 請求參數(shù):String id
- 返回值類型:Teacher
這樣,F(xiàn)eign就可以幫助我們發(fā)送http請求,無需自己使用RestTemplate來發(fā)送了。
StudentController
@RestController
public class StudentController implements Serializable {
@Autowired
TeacherServiceFeign teacherServiceFeign;
@GetMapping("/getInfo")
public Teacher getInfo(){
Teacher teacher = teacherServiceFeign.getInfo("111");
return teacher;
}
}測試
GET http://localhost:8002/getInfo
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Date: Tue, 17 Oct 2023 02:46:43 GMT
Keep-Alive: timeout=60
Connection: keep-alive
{
"name": "張三-111",
"sex": "男"
}自定義配置
Feign可以支持很多的自定義配置,如下表所示:
| 類型 | 作用 | 說明 |
|---|---|---|
| feign.Logger.Level | 修改日志級別 | 包含四種不同的級別:NONE、BASIC、HEADERS、FULL |
| feign.codec.Decoder | 響應結(jié)果的解析器 | http遠程調(diào)用的結(jié)果做解析,例如解析json字符串為java對象 |
| feign.codec.Encoder | 請求參數(shù)編碼 | 將請求參數(shù)編碼,便于通過http請求發(fā)送 |
| feign. Contract | 支持的注解格式 | 默認是SpringMVC的注解 |
| feign. Retryer | 失敗重試機制 | 請求失敗的重試機制,默認是沒有,不過會使用Ribbon的重試 |
一般情況下,默認值就能滿足我們使用,如果要自定義時,只需要創(chuàng)建自定義的@Bean覆蓋默認Bean即可。
到此這篇關(guān)于SpringCloud之OpenFeign調(diào)用解讀的文章就介紹到這了,更多相關(guān)SpringCloud OpenFeign調(diào)用解讀內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實現(xiàn)省市區(qū)轉(zhuǎn)換成樹形結(jié)構(gòu)
這篇文章主要為大家詳細介紹了java實現(xiàn)省市區(qū)轉(zhuǎn)換成樹形結(jié)構(gòu),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08
java Disruptor構(gòu)建高性能內(nèi)存隊列使用詳解
這篇文章主要為大家介紹了java Disruptor構(gòu)建高性能內(nèi)存隊列使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12
SpringBoot中Elasticsearch的連接配置原理與使用詳解
Elasticsearch是一種開源的分布式搜索和數(shù)據(jù)分析引擎,它可用于全文搜索、結(jié)構(gòu)化搜索、分析等應用場景,本文主要介紹了SpringBoot中Elasticsearch的連接配置原理與使用詳解,感興趣的可以了解一下2023-09-09
maven?scope?provided和runtime的例子說明
這篇文章主要介紹了maven?scope?provided和runtime的例子說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
Spring boot自定義http反饋狀態(tài)碼詳解
這篇文章主要給大家介紹了Spring boot自定義http反饋狀態(tài)碼的相關(guān)資料,文中介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面跟著小編一起來學習學習吧。2017-06-06
MySQL查詢字段實現(xiàn)字符串分割split功能的示例代碼
本文主要介紹了MySQL查詢字段實現(xiàn)字符串分割split功能的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01

