Feign配置

一 默认配置

  • 解码器(Decoder):bean名称为feignDecoder,ResponseEntityDecoder类,

  • 编码器(Encoder):bean名称为feignEecoder,SpringEncoder类。

  • 日志(Logger): bean名称为feignLogger,Slf4jLogger类。

  • 注解翻译器(Contract): bean名称为feignContract,SpringMvcContract类。

  • Feign实例的创建者(Feign.Builder):bean名称为feignBuilder,HystrixFeign.Builder类。

  • Feign客户端(Client):bean名称为feignClient,LoadBalancerFeignClient类。

二 自定义注解翻译器

1 新定义一个注解

package org.crazyit.cloud.contract;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyUrl {

    String url();
    String method();
}

2 自定义注解翻译器

package org.crazyit.cloud.contract;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.springframework.cloud.netflix.feign.support.SpringMvcContract;

import feign.MethodMetadata;

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

}

3 编写配置类

package org.crazyit.cloud.contract;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import feign.Contract;

@Configuration
public class MyConfig {

    @Bean
    public Contract feignContract() {
        return new MyContract();
    }
}

4 接口类使用注解

package org.crazyit.cloud;

import org.crazyit.cloud.contract.MyUrl;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient("spring-feign-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();
} 

5 重构服务端的控制器

package org.crazyit.cloud;

import javax.servlet.http.HttpServletRequest;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PoliceController {

    @RequestMapping(value = "/call/{id}", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public Police call(@PathVariable Integer id, HttpServletRequest request) {
        Police p = new Police();
        p.setId(id);
        p.setName("angus");
        p.setMessage(request.getRequestURL().toString());
        return p;
    }
    
    @RequestMapping(value = "/hello/{name}", method = RequestMethod.GET)
    public String hello(@PathVariable String name) {
        return "Hello, " + name;
    }
    
    @RequestMapping(value = "/hellowd", method = RequestMethod.GET)
    public String helloWithOutArg() {
        return "Hello World";
    }
}

6 重构客户端的控制器

package org.crazyit.cloud;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    
    @Autowired
    private HelloClient helloClient;

    @RequestMapping(method = RequestMethod.GET, value="/router")
    public String router() {
        String result = helloClient.hello("angus");
        return result;
    }

    @RequestMapping(method = RequestMethod.GET, value="/police",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public Police getPolice() {
        Police p = helloClient.getPolice(1);
        return p;
    }
    
    @RequestMapping(method = RequestMethod.GET, value="/myhello")
    public String myHello() {
        return helloClient.myHello();
    }
}

7 测试

三 可选配置

  • Logger.Level:接口日志的记录级别,相当于调用了Fiegn.Builder的logLevel方法。

  • Retryer:重试处理器,相当于调用了Fiegn.Builder的retryer方法。

  • ErrorDecoder:异常解码器,相当于调用了Fiegn.Builder的errorDecoder方法。

  • Request.Options:设置请求的配置项,相当于调用了Fiegn.Builder的options方法。

  • Collection<RequestInterceptor>:设置请求拦截器,相当于调用了Fiegn.Builder的requestInterceptors方法。

四 配置多个拦截器

@Bean
public RequestInterceptor getRequestInterceptorsA() {
    return new RequestInterceptor() {
        public void apply(RequestTemplate template) {
            System.out.println("这是第一个请求拦截器");
        }            
    };
}

@Bean
public RequestInterceptor getRequestInterceptorsB() {
    return new RequestInterceptor() {
        public void apply(RequestTemplate template) {
            System.out.println("这是第二个请求拦截器");
        }            
    };
}

五 压缩配置

猜你喜欢

转载自blog.csdn.net/chengqiuming/article/details/81143791