场景:现在有一个客户端是MECHANT,现在我想使用feign访问它的api.但是此时我本地需要使用不同的配置方式访问,例如不同的编解码等;
问题:如果使用两个接口的注解为:
1)
@FeignClient(value = "MECHANT", configuration = MyClientA.MyFeignConfig.class)
2)
@FeignClient(value = "MECHANT", configuration = MyClientB.MyFeignConfig.class)
那么此时会已经注册了名为MECHANT的错误,如果使用简单粗暴的方式修改覆盖之前的bean:
spring:
main:
allow-bean-definition-overriding: true
虽然解决了报错,但是因为覆盖的原因,无法将多种配置生效;这种方式可以解决将多个feign请求方法分到不同接口的场景,但是在这里不适用;
解决:
使用手动创建feign代理类的方式解决,贴出完整代码:
@FeignClient(value = "MECHANT", configuration = MyClientA.MyFeignConfig.class)
public interface MyClientA {
@PostMapping(value = "get2")
Student get(@RequestBody Student student);
@Component
class MyFeignConfig {
@Bean
public MyBase64EnCoder myBase64EnCoder() {
return new MyBase64EnCoder();
}
class MyBase64EnCoder implements Decoder {
@Override
public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
System.out.println(1);
return new Gson().fromJson(response.body().asReader(),type);
}
}
}
}
public interface MyClientB {
@PostMapping(value = "get2")
Student get(@RequestBody Student student);
}
@Component
@Import(FeignClientsConfiguration.class)
public class MyClientBuilder {
private MyClientB myClientB;
public MyClientB getMyClientB() {
return myClientB;
}
public void setMyClientB(MyClientB myClientB) {
this.myClientB = myClientB;
}
public MyClientBuilder(Decoder mm, Encoder encoder, Client client, Contract contract) {
this.myClientB = Feign.builder().client(client)
.encoder(encoder)
.decoder(decoder())
.contract(contract)
//默认是Logger.NoOpLogger
.logger(new Slf4jLogger(MyClientB.class))
//默认是Logger.Level.NONE
.logLevel(Logger.Level.FULL)
.target(MyClientB.class, "http://MECHANT");
}
@Bean
public MyDecoder decoder() {
return new MyDecoder();
}
class MyDecoder implements Decoder {
@Override
public Object decode(Response response, Type type) throws IOException, FeignException {
System.out.println(2);
return new Gson().fromJson(response.body().asReader(), type);
}
}
}
调用:
@RefreshScope
@RestController
public class ClientControllerNacos {
@Autowired
MyClientA myClientNacos;
@Autowired
MyClientBuilder myClientBuilder;
@Value("${gao}")
public String gao;
@GetMapping("get2")
public Object get(Student student) {
return myClientNacos.get(student);
}
@GetMapping("get3")
public Object get3(Student student) {
return myClientNacos.get(student);
}
}