@FeignClient相同value出现报错~实现同客户端不同配置访问

/ 后端 / 没有评论 / 341浏览

场景:现在有一个客户端是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 {
<span class="hljs-meta">@PostMapping(value = "get2")</span>
Student <span class="hljs-title function_">get</span><span class="hljs-params">(<span class="hljs-meta">@RequestBody</span> Student student)</span>;

<span class="hljs-meta">@Component</span>
<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyFeignConfig</span> {

    <span class="hljs-meta">@Bean</span>
    <span class="hljs-keyword">public</span> MyBase64EnCoder <span class="hljs-title function_">myBase64EnCoder</span><span class="hljs-params">()</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyBase64EnCoder</span>();
    }

    <span class="hljs-keyword">class</span> <span class="hljs-title class_">MyBase64EnCoder</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Decoder</span> {

        <span class="hljs-meta">@Override</span>
        <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">decode</span><span class="hljs-params">(Response response, Type type)</span> <span class="hljs-keyword">throws</span> IOException, DecodeException, FeignException {
            System.out.println(<span class="hljs-number">1</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Gson</span>().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);
    }

}