Feign 版本10.1.0
Spring 版本 5.1.5.RELEASE
SpringBoot 版本 2.1.5.RELEASE
SpringCloud 版本 2.1.1.RELEASE
在微服务架构中,当我们需要进行服务间调用时可以选择feign组件,
现在遇到的问题是: 当同一个服务,声明多个feign实例时,启动时直接报错。
解决办法,通过 Feign.builder() 手动生成代理类。 另一种见评论区:#允许bean实例同名覆盖allow-bean-definition-overriding: true
1.定义接口:
2.配置接口代理
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.alibaba.fastjson.support.springfox.SwaggerJsonSerializer;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import com.yunplus.bpg.cloud.file.proxy.client.QcloudClient;
import com.yunplus.bpg.cloud.file.proxy.client.TaskClient;
import feign.Contract;
import feign.Feign;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.http.MediaType;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* Feign配置类,负责实例化所需要的伪客户端
*/
@Component
public class RemoteXxxClient {
public final static String SERVICE_ID = "XXX-SERVICE-ID";
/**
* FeignClientFactoryBean 该工厂类中 设置builder属性时就是通过该对象,源码中可看到
*/
protected FeignContext feignContext;
/**
* 通过注入Eureka实例对象,就不用手动指定url,只需要指定服务名即可
*/
protected EurekaClient eurekaClient;
private static final Map FEIGN_CLIENTS = new ConcurrentHashMap<>();
@Autowired
public void init(final EurekaClient eurekaClient, final FeignContext feignContext) {
this.eurekaClient = eurekaClient;
this.feignContext = feignContext;
}
@Bean
public AbcClient getQcloudService() {
return create(AbcClient.class, SERVICE_ID);
}
@Bean
public DefClient getTaskService() {
return create(DefClient.class, SERVICE_ID);
}
/**
* 设置编码解码器为FastJson
*
* @param clazz
* @param serverId
* @param
* @return
*/
protected T create(Class clazz, String serverId) {
InstanceInfo nextServerFromEureka = eurekaClient.getNextServerFromEureka(serverId, false);
String key = nextServerFromEureka.getIPAddr() + ":" + nextServerFromEureka.getPort() + ":" + clazz.getName();
Object object = FEIGN_CLIENTS.get(key);
if (Objects.isNull(object)) {
object = Feign.builder()
//encoder指定对象编码方式
.encoder(this.feignEncoder())
//decoder指定对象解码方式
.decoder(this.feignDecoder())
//.client(feignClient)
//options方法指定连接超时时长及响应超时时长
.options(new Request.Options(5000, 5000))
//retryer方法指定重试策略
//.retryer(new Retryer.Default(5000, 5000, 3))
.contract(feignContext.getInstance(serverId, Contract.class))
//target方法绑定接口与服务端地址。返回类型为绑定的接口类型。
.target(clazz, nextServerFromEureka.getHomePageUrl());
FEIGN_CLIENTS.put(key, object);
}
return (T) object;
}
protected Encoder feignEncoder() {
return new SpringEncoder(feignHttpMessageConverter());
}
protected Decoder feignDecoder() {
return new SpringDecoder(feignHttpMessageConverter());
}
/**
* 设置解码器为fastjson
*
* @return
*/
private ObjectFactory feignHttpMessageConverter() {
final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(this.getFastJsonConverter());
return () -> httpMessageConverters;
}
private FastJsonHttpMessageConverter getFastJsonConverter() {
FastJsonHttpMessageConverter converter =
new FastJsonHttpMessageConverter();
List supportedMediaTypes = new ArrayList<>();
MediaType mediaTypeJson =
MediaType.valueOf(MediaType.APPLICATION_JSON_UTF8_VALUE);
supportedMediaTypes.add(mediaTypeJson);
converter.setSupportedMediaTypes(supportedMediaTypes);
FastJsonConfig config = new FastJsonConfig();
config.getSerializeConfig().put(JSON.class, new SwaggerJsonSerializer());
config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);
converter.setFastJsonConfig(config);
return converter;
}
}
3.调用
PS:
Original: https://www.cnblogs.com/phpdragon/p/12119128.html
Author: phpdragon
Title: SpringCloud : 多个 @FeignClient 注解 value 设置为同一个应用的解决方案
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/541334/
转载文章受原作者版权保护。转载请注明原作者出处!