一 默认配置
-
解码器(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("这是第二个请求拦截器");
}
};
}
五 压缩配置
-
feign.compression.request.enabled:设置为true开启请求压缩。
-
feign.compression.response.enabled:设置为true开户响应压缩。
-
feign.compression.request.mime-types:数据类型列表,默认值为text/xml, application/xml, application/json。
-
feign.compression.request.min-request-size:设置请求内容的最小阀值,默认值为2048。