Feign簡介
Feign 是一個聲明web服務用戶端,這便得編寫web服務用戶端更容易,使用Feign 建立一個接口并對它進行注解,它具有可插拔的注解支援包括Feign注解與JAX-RS注解,Feign還支援可插拔的編碼器與解碼器,Spring Cloud 增加了對 Spring MVC的注解,Spring Web 預設使用了HttpMessageConverters, Spring Cloud 內建 Ribbon 和 Eureka 提供的負載均衡的HTTP用戶端 Feign。
運用前面的三個項目基礎上給Invoker端添加Feign。
- 添加Feign的maven坐标:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
- 應用主類中通過@EnableFeignClients注解開啟Feign功能
:
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class InvokerApp {
public static void main(String[] args) {
new SpringApplicationBuilder(InvokerApp.class).web(true).run(args);
}
}
-
定義HelloClient
接口,使用@FeignClient(“Spring-fegin-provider”)注解來綁定該接口對應Spring-fegin-provider服務。
@FeignClient("Spring-fegin-provider")
public interface HelloClient {
@RequestMapping(method = RequestMethod.GET, value="/hello/{name}")
String hello(@PathVariable("name") String name);
@RequestMapping(method = RequestMethod.GET, value="/call/{id}")
Police getPolice(@PathVariable("id") Integer id);
@MyUrl(url = "/hellowd", method = "GET")
String myHello();
}
- @MyUrl為自定義的注解翻譯器:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyUrl {
String url();
String method();
}
- 繼承SpringMvcContract 原有的翻譯器,在SpringMvcContract 基礎上實作自己定義的MyUrl
:
public class MyContract extends SpringMvcContract {
@Override
protected void processAnnotationOnMethod(MethodMetadata data,
Annotation annotation, Method method) {
super.processAnnotationOnMethod(data, annotation, method);
// 注解是MyUrl類型的,才處理
if(MyUrl.class.isInstance(annotation)) {
System.out.println("############# 這是自定義翻譯器");
MyUrl myUrl = method.getAnnotation(MyUrl.class);
String url = myUrl.url();
String httpMethod = myUrl.method();
data.template().method(httpMethod);
data.template().append(url);
}
}
}
- 自動配置MyContract:
@Configuration
public class MyConfig {
@Bean
public Contract feignContract() {
return new MyContract();
}
}
- 在web層中調用上面定義的TestController :
@RestController
public class TestController {
@Autowired
private HelloClient helloClient;
@RequestMapping(method = RequestMethod.GET, value="/router")
public String router() {
String result = helloClient.hello("jack");
return result;
}
@RequestMapping(method = RequestMethod.GET, value="/police",
produces = MediaType.APPLICATION_JSON_VALUE)
public Police getPolice() {
Police p = helloClient.getPolice();
return p;
}
@RequestMapping(method = RequestMethod.GET, value="/myhello")
public String myHello() {
return helloClient.myHello();
}
}