问题
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