1 介紹
Feign 是一個聲明式的 REST 用戶端,它能讓 REST 調用更加簡單。Feign 提供了 Http 請求的模闆,通過編寫簡單的忌口和插入注解,就可以定義好 Http 請求的參數、格式、位址等資訊。
之前使用的是 RestTemplate 通路 Rest 服務,RestTemplate 提供了多種便捷通路遠端 Http 服務的方法,能夠大大提高用戶端的編寫效率。
而 Feign 會完全代理 Http 請求,我們隻需要湘調用方法一樣調用它就可以完成服務請求及相關處理。Feign 可以與 Eureka 和 Ribbon 組合使用以支援負載均衡。
2 內建 Feign
聲明式的 REST 用戶端,即注解式的接口調用,類似于 Mapper 接口一樣。在服務消費者子產品添加如下資訊(之前項目)。
2.1 pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.2 Service
建立 UserInfo Service 接口
@FeignClient(value = "springcloud-provider", path = "/users")
public interface UserInfoService {
@RequestMapping(value = "/{username}")
UserInfo getByName(@PathVariable(value = "username") String username);
}
使用 @PathVariable 時,value 需要顯式聲明,否則報錯。
2.3 Controller
@RestController
@RequestMapping(value = "users")
public class UserInfoController {
@Autowired
UserInfoService userInfoService;
/**
* 通過使用者名擷取使用者
* @param username
* @return
*/
@GetMapping(value = "/feign/{username}")
public UserInfo getByFeign(@PathVariable String username) {
UserInfo userInfo = userInfoService.getByName(username);
return userInfo;
}
}
2.4 啟動類
@SpringBootApplication
@EnableEurekaClient // 表明自己是個 eureka 用戶端,會自動注冊到 eureka 服務端中
@EnableFeignClients(basePackages = {"com.pky.springcloud"}) // 指定掃描 Feign 相關注解。
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
如果 Feign 接口定義跟啟動類不在一個包名下,則需要指定掃描的包名 @EnableFeignClients(basePackages = “指定掃描路徑”)
2.5 啟動測試
浏覽器輸入對應位址。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNyZuBnL2kjNyADNyMTM3ITNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
多次請求之後觀察 9001、9002 控制台,輪詢輸出對應資訊,達到了負載均衡的效果。
2.6 自定義認證
Feign 有提供一個接口 RequestInterceptor,即請求攔截器。在請求之前做認證操作,然後往請求頭中設定認證之後的資訊。通過實作 RequestInterceptor 接口來自定義認證方式。
/**
* Feign 認證攔截器
*/
@Configuration
public class FeignBasicAuthRequestInterceptor implements RequestInterceptor {
public FeignBasicAuthRequestInterceptor() {
}
@Override
public void apply(RequestTemplate requestTemplate) {
// 業務邏輯
requestTemplate.header("token", "FeignToken");
}
}
建立 Feign 配置類:
/**
* Feign 配置類
*/
@Configuration
public class FeignConfig {
/**
* 認證攔截器
* @return
*/
@Bean
public FeignBasicAuthRequestInterceptor basicAuthRequestInterceptor(){
return new FeignBasicAuthRequestInterceptor();
}
/**
* 日志級别
* @return
*/
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
還需要在 Feign 接口中引用該配置:
@FeignClient(value = "springcloud-provider", path = "/users", configuration = FeignConfig.class)
public interface UserInfoService {
@RequestMapping(value = "/{username}")
UserInfo getByName(@PathVariable(value = "username") String username);
}
服務提供者子產品中的 Controller 接口:
@RestController
@RequestMapping(value = "users")
public class UserInfoController {
@Autowired
UserInfoService userInfoService;
/**
* 通過使用者名擷取使用者
* @param username
* @return
*/
@GetMapping(value = "/{username}")
public UserInfo getByName(@PathVariable String username, HttpServletRequest request) {
String token = request.getHeader("token");
UserInfo userInfo = userInfoService.getByUsername(username);
return userInfo;
}
}
以上完成自定義認證。
2.7 日志
若接口調用失敗、參數沒收到等問題,就需要配置 Feign 的日志。
* Feign 配置類
*/
@Configuration
public class FeignConfig {
/**
* 認證攔截器
* @return
*/
@Bean
public FeignBasicAuthRequestInterceptor basicAuthRequestInterceptor(){
return new FeignBasicAuthRequestInterceptor();
}
/**
* 日志級别
* @return
*/
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
日志類别:
- NONE: 不輸出日志
- BASIC:隻輸出請求方法的 URL 和響應的狀态碼以及接口執行的時間
- HEADERS:将 BASIC 資訊和請求頭資訊輸出
- FULL: 輸出完整的請求資訊
在 application.yml 中配置日志資訊
# 日志
logging:
level:
com:
pky:
springcloud: DEBUG
level 後面為指定包路徑。
調用接口時,控制台會列印相應資訊: