項目進行遇到一個問題,就是我們每增加一個服務調用的時候,基本都是增加一個Feign接口,這樣可能會面臨尴尬的問題,不同的URL調用時,會copy一堆的Feign接口,這顯然不是我們最佳的方案,如果能使用一個Feign接口,在不同邏輯下動态請求不同的URL,同時不同的URL攜帶不同的Token資訊…
TestFeignClient FeignClient接口:
@FeignClient(name = "TetsFeignClient")
public interface TestFeignClient {
@RequestLine("GET /test/healthcheck")
Object healthcheck(URI baseUri, @HeaderMap Map<String,Object> map);
@RequestLine("GET /test/{serverId}")
String getSomething2(URI baseUri, @Param("serverId") String serverId);
@RequestLine("POST /test/list")
Object list(URI baseUri,@HeaderMap Map<String,Object> map, QueryParam param);
application.yml配置如下:
api:
test:
homeUrl: http://xxx.test.com
TestCallerService 服務類,使用時直接注入這個Service即可
import xxx;
@Slf4j
@Component
@Import(FeignClientsConfiguration.class)
public class TestCallerService {
private TestFeignClient testFeignClient;
private URI uri;
//構造方法依賴yam檔案中的參數,需要@Value注入對應的參數
public TestCallerService(Decoder decoder, Encoder encoder,@Value("${api.test.homeUrl}")String testHomeUrl) {
testFeignClient= Feign.builder()
.encoder(encoder)
.decoder(decoder)
.target(Target.EmptyTarget.create(TestFeignClient.class));
initUrl(testHomeUrl);
}
private void initUrl(String testHomeUrl){
try {
uri = new URI(testHomeUrl);
}catch (Exception e) {
log.info("初始化,{},{} TestClient error", testHomeUrl, e);
}
}
public Boolean healthcheck(String token){
try {
//我這裡是接口測試使用的Object接收,自己根據實際情況轉換成對應的DTO對象即可
Object result= testFeignClient.healthcheck(uri, handleRequestHeadInfo(token));
//...對應的接口調用邏輯處理
//...
}catch (Exception e){
//...對應的異常邏輯處理
}
}
/**
* 封裝請求頭部資訊
* @param token
* @return
*/
private Map<String,Object> handleRequestHeadInfo(String token){
return ImmutableMap.of("Authorization",token,"Content-Type","application/json;charset=UTF-8");
}
上述實作總結:
1、FeignClient 中不要寫url, 使用 @RequestLine修飾方法
2、調用地方必須引入 FeignClientConfiguration, 必須有Decoder, Encoder
3、調用類必須以建構函數(Constructor) 的方式注入 FeignClient 類
4、傳入URL作為參數;