SpringCloudOpenFeign 動态Url
- 1. 需求描述
- 2. 實作方案
- 3. 細節分析
1. 需求描述
一般情況下,微服務内部調用都是通過注冊中心,eureka,zookeeper,nacos等實作動态調用,但是對于一些外部http調用,對于不在同一微服務内,不在同一注冊中心的服務調用,可以考慮SpringCloudOpenFeign,而且可以實作動态URL,通過參數動态控制。
2. 實作方案
服務端正常springboot項目,也不一定是springboot項目,隻要正常提供RESTFul接口就可以,本次測試以springboot為例。主要是用戶端調用。
- 服務端:
/**
* (Category)控制層
*
* @author makejava
* @since 2021-06-03 07:20:41
*/
@RestController
@RequestMapping("/category")
public class CategoryController {
/**
* 服務對象
*/
@Resource
private CategoryService categoryService;
/**
* 測試服務
*/
@GetMapping("/test")
public Response test() {
return Response.createSuccessResponse("查詢成功", "我是測試服務");
}
}
- 用戶端
maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
用戶端代碼
/**
* 測試
* @author zrj
* @since 2021-07-25
*/
@Api(value = "微盟鑒權測試")
@RestController
@RequestMapping("/weimob")
public class ActivityController {
@Resource
private CategoryService categoryService;
@GetMapping("/test")
@ApiOperation(value = "微盟擷取Code")
public Response test() throws URISyntaxException {
System.out.println("-----測試-----");
URI uri = new URI("http://localhost:8080/category/test");
Response response = categoryService.test(uri);
return Response.createSuccessResponse("查詢成功", response);
}
}
調用接口
/**
* 測試接口Openfeign
* @author zrj
* @since 2021/7/25
**/
@Service("WeimobAuthorize")
@FeignClient(url = "http://localhost:8080/category", name = "CategoryService")
public interface CategoryService {
@GetMapping
Response test(URI uri);
}
3. 細節分析
1.接口使用SpringMVC注解
接口方法的定義使用了SpringMVC的注解 @GetMapping、@RequestParam,其實SpringMVC的其他注解在此處都是支援的。(有其他文章提到也支援OpenFeign原有的注解@RequestLine、@Param等,但部落客實測是不支援的,相關解析類為 feign.Contract,這個存疑)。
2.springcloud openfeign自動建構實作類
在使用方式上,OpenFeign需要手動建構代理對象,Spring Cloud OpenFeign 不同于 OpenFeign, Spring Cloud OpenFeign 幫我們自動生成了接口的代理對象(即實作類),并且注冊到Spring中,我們可以很友善的使用 @Autowired 注入代理對象然後使用。其預設的代理對象是 LoadBalancerFeignClient。還有一個代理對象是 feign.Client.Default。兩者差別在于:LoadBalancerFeignClient 通過服務名(下文提到)從Eureka查找相關的節點位址url,發起調用。feign.Client.Default 僅是簡單的直接調用。
3.FeignClient屬性name與URL一定要指定
@FeignClient(url = “http://localhost:8080/category”, name = “CategoryService”)
name 屬性,是@FeignClient 注解必要的,不定義時會報錯其預設指代Eureka上的服務名。
url 屬性,一定要指定,這是重點了! url屬性指定什麼值其實不重要,因為最終都會被方法的URI參數值替換掉,它在這裡另一個重要的作用,就是将接口的代理對象變成feign.Client.Default(上文提到預設是LoadBalancerFeignClient),這樣就繞過了從Eureka取節點位址這一步,畢竟第三方的位址不可能注冊到我們的Eureka上。(相關細節可自行debug FeignClientFactoryBean.getTarget())