Spring cloud無(wú)縫集成Feign的使用示例詳解
Feign的作用
Feign是Netflix公司開發(fā)的聲明式web客戶端組件,Spring對(duì)Feign做了無(wú)縫集成:
Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Eureka, as well as Spring Cloud LoadBalancer to provide a load-balanced http client when using Feign.
可以通過(guò)Feign注解或JAX-RS注解使用,F(xiàn)eign也支持拔插式的編解碼。Spring Cloud增加了對(duì)Spring MVC注解的支持,并且在SpringMVC項(xiàng)目中默認(rèn)使用HttpMessageConverters 轉(zhuǎn)換器。同時(shí),Spring Cloud集成了Eureka、Spring Cloud LoadBalancer等組件,以提供在使用Feign組件時(shí)的負(fù)載均衡。
為什么要使用Feign
由于Spring6.0之后有了自己的Web客戶端組件,所以在Spring Cloud2022之后,Spring官方其實(shí)是在逐步的移除Feign、而使用自己的Web客戶端組件作為替代。
但是不管是誰(shuí),我們項(xiàng)目中都需要一個(gè)比RestTemplate更加靈活的Web客戶端組件。因?yàn)镽estTemplate使用起來(lái)確實(shí)非常不方便:
public User getUserByRestTemplate(){
String url="http://userservice/user/getUser";
System.out.println("url"+url);
// int c = 1/0;
return restTemplate.getForObject(url,User.class);
}應(yīng)用中會(huì)有很多地方需要調(diào)用微服務(wù)userservice的接口,每一個(gè)調(diào)用的地方都需要寫url,代碼會(huì)顯得非常凌亂、不優(yōu)雅、不易維護(hù)。
Feign可以完美解決以上RestTemplate的問(wèn)題,尤其是Spring Cloud整合Eureka和Spring LoadBalancer之后,還可以輕松實(shí)現(xiàn)負(fù)載均衡。
Feign的使用
pom文件引入openfeign
我們以前面幾篇文章的案例為基礎(chǔ),在Eureka、Spring LoadBalancer、Hystrix框架基礎(chǔ)上搭建Feign。
首先在orderservice模塊下,pom文件引入openFeign:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springCloud</artifactId>
<groupId>com.example</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>orderservice</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>userService</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>orderService啟動(dòng)類啟用FeignClients
在orderService的啟動(dòng)類中通過(guò)@EnableFeignClients注解啟用FeignClient:
package com;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
@EnableFeignClients
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}RestTemplate就可有可無(wú)了,無(wú)需理會(huì)。
編寫FeignClient接口
創(chuàng)建一個(gè)接口文件UserService
@FeignClient(name="userservice",path="/user")
public interface IUserService {
@GetMapping("/getUser")
public User getUser();
}通過(guò)@FeignClient注解,指定當(dāng)前接口是一個(gè)FeignClient的接口文件,其中name屬性指定其對(duì)應(yīng)的微服務(wù)名稱,path指定對(duì)該服務(wù)的訪問(wèn)路徑。
接口方法支持SpringMVC的注解,比如@GetMapping、@PostMapping等等,相當(dāng)于是在訪問(wèn)當(dāng)前服務(wù)下的Controller方法一樣。這為程序員在微服務(wù)環(huán)境下的服務(wù)調(diào)用提供了極大的方便,使得微服務(wù)調(diào)用變的輕而易舉。
尤其,這個(gè)接口是不需要我們?nèi)?shí)現(xiàn)的,由Feign在Spring Cloud服務(wù)啟動(dòng)過(guò)程中通過(guò)代理實(shí)現(xiàn)并自動(dòng)注入到Spring Ioc容器中。所以我們?cè)趹?yīng)用中可以直接通過(guò)自動(dòng)裝配引用。
回想一下MyBatis,和Mapper接口是否很類似?
對(duì)接口方法的調(diào)用
找到我們以前通過(guò)RestTemplate調(diào)用userservice服務(wù)的應(yīng)用,通過(guò)@AutoWired注解自動(dòng)裝配IUserService ,直接調(diào)用接口方法getUser():
@Service
@Slf4j
public class OrderService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private IUserService userService;
public String getOrder(){
//通過(guò)userService獲取user信息
// User user = getUserByRestTemplate();
User user = getUserByFeign();
// System.out.println(user);
return user.getName();
}
public User getUserByRestTemplate(){
String url="http://userservice/user/getUser";
System.out.println("url"+url);
// int c = 1/0;
return restTemplate.getForObject(url,User.class);
}
public User getUserByFeign(){
return userService.getUser();
}
}測(cè)試
分別啟動(dòng)Eureka模塊、orderservice模塊、userservice模塊:

瀏覽器訪問(wèn)測(cè)試:

說(shuō)明Feign已經(jīng)正常工作。
反復(fù)刷新訪問(wèn):



說(shuō)明Spring LoadBalancer已經(jīng)正常工作。
在使用RestTemplate作為WEB客戶端的時(shí)候,我們需要通過(guò)@LoadBalanced注解來(lái)啟用Spring LoadBalancer負(fù)載均衡,但是FeignClient并不需要做什么,自動(dòng)集成了負(fù)載均衡。
集成Hystrix
orderService服務(wù)的Controller中增加@HystrixCommand配置:
@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {
@Autowired
OrderService orderService;
@Autowired
FallbackHandle fallbackHandle;
@GetMapping("/getOrder")
@HystrixCommand(fallbackMethod = "fallback",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000")
})
public String getOrder(){
log.info("Come here to get Order....123===");
return orderService.getOrder();
}
public String fallback(){
return "orderService服務(wù)異常";
}
}然后userservice的getUser方法添加sleep使其超時(shí):
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@Value("${server.port}")
private String serverPort;
@GetMapping("/getUser")
@HystrixCommand(fallbackMethod = "fallback",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "8000")
})
public User getUser(){
log.info("userController's getuser comming......");
User user=new User();
user.setName("zhangsan from:"+serverPort);
try{
log.info("I am sleepint for 10 second");
Thread.sleep(10*1000);
log.info("I weekup");
}catch (Exception e){
}
return user;
}
public User fallback(){
User user=new User();
user.setName("userService服務(wù)異常");
return user;
}
}前端訪問(wèn)驗(yàn)證:

如果修改userService的@HystrixCommand超時(shí)時(shí)長(zhǎng)參數(shù)為2秒,則:

說(shuō)明Hystrix組件已經(jīng)可以正常工作,與Feign組件進(jìn)行了無(wú)縫集成。
Spring cloud feign官網(wǎng):https://cloud.spring.io/spring-cloud-openfeign/reference/html...
以上就是Spring cloud無(wú)縫集成Feign的使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Spring cloud無(wú)縫集成Feign的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java8 Stream中對(duì)集合數(shù)據(jù)進(jìn)行快速匹配和賦值的代碼示例
這篇文章主要介紹了Java8 Stream中如何對(duì)集合數(shù)據(jù)進(jìn)行快速匹配和賦值,文中通過(guò)代碼示例為大家介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2023-06-06
詳解springmvc之json數(shù)據(jù)交互controller方法返回值為簡(jiǎn)單類型
這篇文章主要介紹了springmvc之json數(shù)據(jù)交互controller方法返回值為簡(jiǎn)單類型,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05
Java筆記之從IO模型到Netty框架學(xué)習(xí)初識(shí)篇
Netty作為一個(gè)已經(jīng)發(fā)展了十多年的框架,已然非常成熟了,其中有大量的細(xì)節(jié)是普通使用者不知道或者不關(guān)心的,本文帶你查缺補(bǔ)漏掌握Netty的使用2022-03-03
解析Mybatis SqlSessionFactory初始化原理
本文主要介紹了Mybatis SqlSessionFactory初始化原理,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07
Java中注解@Async實(shí)現(xiàn)異步及導(dǎo)致失效原因分析
Async注解用于聲明一個(gè)方法是異步的,當(dāng)在方法上加上這個(gè)注解時(shí)將會(huì)在一個(gè)新的線程中執(zhí)行該方法,而不會(huì)阻塞原始線程,這篇文章主要給大家介紹了關(guān)于Java中注解@Async實(shí)現(xiàn)異步及導(dǎo)致失效原因分析的相關(guān)資料,需要的朋友可以參考下2024-07-07
帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之無(wú)權(quán)無(wú)向圖
這篇文章主要為大家介紹了Java數(shù)據(jù)結(jié)構(gòu)和算法之無(wú)權(quán)無(wú)向圖?,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-01-01
Java 轉(zhuǎn)義字符全解析從基礎(chǔ)語(yǔ)法到安全編碼實(shí)踐(最新推薦)
本文詳細(xì)介紹了Java中的轉(zhuǎn)義字符,包括基礎(chǔ)轉(zhuǎn)義序列、Unicode轉(zhuǎn)義、Java 15的文本塊特性以及在正則表達(dá)式和安全編碼中的應(yīng)用,通過(guò)實(shí)例和最佳實(shí)踐,幫助開發(fā)者正確使用轉(zhuǎn)義字符,提高代碼的正確性和安全性,感興趣的朋友跟隨小編一起看看吧2025-10-10
IDEA創(chuàng)建Java項(xiàng)目保姆級(jí)教程(超詳細(xì)!)
這篇文章主要給大家介紹了關(guān)于IDEA創(chuàng)建Java項(xiàng)目保姆級(jí)教程的相關(guān)資料,Java是一種廣泛使用的編程語(yǔ)言,廣泛用于Web應(yīng)用程序和客戶端應(yīng)用程序的開發(fā),文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09
springboot線程池監(jiān)控的簡(jiǎn)單實(shí)現(xiàn)
本文主要介紹了springboot線程池監(jiān)控的簡(jiǎn)單實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01

