Define different Feign client implementations based on environment

 ̄綄美尐妖づ 提交于 2020-03-18 06:22:48

问题


I have a Spring boot application which uses Feign to call an external web service via Eureka. I'd like to be able to run the application using a mocked out implementation of the Feign interface, so I can run the application locally without necessarily having Eureka or the external web service running. I had imagined defining a run configuration that allowed me to do this, but am struggling to get this working. The issue is that the Spring "magic" is defining a bean for the Feign interface no matter what I try.

Feign interface

@FeignClient(name = "http://foo-service")
public interface FooResource {
    @RequestMapping(value = "/doSomething", method = GET)
    String getResponse();
}

Service

public class MyService {
    private FooResource fooResource;

    ...

    public void getFoo() {
        String response = this.fooResource.getResponse();
        ...
    }
}

I tried adding a configuration class that conditionally registered a bean if the Spring profile was "local", but that was never called when I ran the application with that Spring profile:

@Configuration
public class AppConfig {
    @Bean
    @ConditionalOnProperty(prefix = "spring.profile", name = "active", havingValue="local")
    public FooResource fooResource() {
        return new FooResource() {
            @Override
            public String getResponse() {
                return "testing";
            }
        };
    }
}

At the point my service runs, the FooResource member variable in MyService is of type

HardCodedTarget(type=FoorResource, url=http://foo-service)

according to IntelliJ. This is the type that is automatically generated by the Spring Cloud Netflix framework, and so tries to actually communicate with the remote service.

Is there a way I can conditionally override the implementation of the Feign interface depending on a configuration setting?


回答1:


Having posted the same question on the Spring Cloud Netflix github repository, a useful answer was to use the Spring @Profile annotation.

I created an alternative entry point class that was not annotated with @EnabledFeignClients, and created a new configuration class that defined implementations for my Feign interfaces. This now allows me to run my application locally without the need to have Eureka running, or any dependent services.




回答2:


the solution is like below:

public interface FeignBase {
   @RequestMapping(value = "/get", method = RequestMethod.POST, headers = "Accept=application/json")
   Result get(@RequestBody Token common);
}

then define your env based interface:

@Profile("prod")
@FeignClient(name = "service.name")
public interface Feign1 extends FeignBase 
{}

@Profile("!prod")
@FeignClient(name = "service.name", url = "your url")
public interface Feign2 extends FeignBase 
{}

finally, in your service impl:

@Resource
private FeignBase feignBase;


来源:https://stackoverflow.com/questions/43977983/define-different-feign-client-implementations-based-on-environment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!