天天看點

SpringCloud系列(七)——SpringCloud內建Feign

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();
    }

}
           

繼續閱讀