前言
在《Feign-請求不同注冊中心的服務》中,提到,如果需要請求不同注冊中心的服務,可以設置@FeignClient
的url
屬性。
這種做法有個缺點,需要服務消費者,配置各個環境的url
。
如果服務提供方url
變更,需要通知到服務消費者,如果消費者很多,變更通知也是件麻煩事。
基於java的封裝特性,作為獨立的服務提供者,如果能封裝url
,豈不是更好?
解決方案
服務提供者
//@FeignClient(name = "feign-provider")
public interface CustomizeFeignApi {
@RequestMapping(value = "/customize", method = RequestMethod.GET)
String queryCustomize();
}
@FeignClient
,不需要。加上的話,會自動創建對應bean,達不到手動創建的目的。
自定義配置
@Configuration
@Import(FeignClientsConfiguration.class)
public class FeignClientConfig {
@Bean
public CustomizeFeignApi customizeFeignApi(Contract contract, Decoder decoder, Encoder encoder) {
return Feign.builder().contract(contract).encoder(encoder).decoder(decoder).target(CustomizeFeignApi.class, "http://localhost:8004");
}
}
@Configuration
:需要被消費者應用掃描到。
@Import(FeignClientsConfiguration.class)
:如果消費者上下文不存在Contract
, Decoder
, Encoder
,由FeignClientsConfiguration
提供默認bean。
以上,可封裝為jar
,上傳到公司nexus私服,有消費者下載使用。
服務消費者
依賴上文的jar。
<!--服務提供者-->
<dependency>
<groupId>com.wxs.springcloud</groupId>
<artifactId>springcloud-sample-feign-provider-spi</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
注入使用。
@RestController
public class CustomizeFeignTestController {
@Autowired
private CustomizeFeignApi customizeFeignApi;
@GetMapping("/customize")
public String query() {
return customizeFeignApi.queryCustomize();
}
}
啟動類,添加掃描。
@ComponentScan("com.wxs.feign.provider.api")
驗證
遇到的問題
Method not annotated with HTTP method type (ex. GET, POST)
Caused by: java.lang.IllegalStateException: Method queryCustomize not annotated with HTTP method type (ex. GET, POST)
at feign.Util.checkState(Util.java:128) ~[feign-core-9.5.0.jar:na]
at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:97) ~[feign-core-9.5.0.jar:na]
at feign.Contract$BaseContract.parseAndValidatateMetadata(Contract.java:64) ~[feign-core-9.5.0.jar:na]
at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:146) ~[feign-core-9.5.0.jar:na]
at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:53) ~[feign-core-9.5.0.jar:na]
at feign.Feign$Builder.target(Feign.java:218) ~[feign-core-9.5.0.jar:na]
at feign.Feign$Builder.target(Feign.java:214) ~[feign-core-9.5.0.jar:na]
at com.wxs.feign.consumer.config.FeignClientConfig.customizeFeignApi(FeignClientConfig.java:38) ~[classes/:na]
feign.Feign.Builder
默認提供的是:new Contract.Default()
。
需要指定Contract
為SpringMvcContract
。
Feign.builder().contract(new SpringMvcContract()).target(CustomizeFeignApi.class, "http://localhost:8004")
參考
Creating Feign Clients Manually
Feign: Method not annotated with HTTP method type (ex. GET, POST)