根据环境定义不同的Feign客户端实现

时间:2017-05-15 11:11:30

标签: spring-boot spring-cloud-netflix netflix-feign spring-cloud-feign

我有一个Spring启动应用程序,它使用Feign通过Eureka调用外部Web服务。我希望能够使用模拟的Feign接口实现来运行应用程序,因此我可以在本地运行应用程序而无需运行Eureka或外部Web服务。我曾想象定义一个允许我这样做的运行配置,但我正在努力让这个工作。问题在于Spring"魔术"正在为Feign界面定义一个bean,无论我尝试什么。

Feign界面

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

服务

public class MyService {
    private FooResource fooResource;

    ...

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

我尝试添加一个有条件地注册bean的配置类,如果Spring配置文件是" local",但是当我使用Spring配置文件运行应用程序时从未调用过:

@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";
            }
        };
    }
}

在我的服务运行时,FooResource中的MyService成员变量的类型为

  

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

根据IntelliJ的说法。这是Spring Cloud Netflix框架自动生成的类型,因此尝试实际与远程服务进行通信。

有没有办法可以根据配置设置有条件地覆盖Feign接口的实现?

3 个答案:

答案 0 :(得分:3)

Spring Cloud Netflix github存储库上发布了相同的问题,一个有用的答案是使用Spring @Profile注释。

我创建了一个未使用@EnabledFeignClients注释的替代入口点类,并创建了一个新的配置类,用于定义我的Feign接口的实现。现在,这使我可以在本地运行我的应用程序,而无需运行Eureka或任何相关服务。

答案 1 :(得分:1)

解决方案如下:

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

然后定义基于env的界面:

@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 
{}

最后,在您的服务暗示中:

@Resource
private FeignBase feignBase;

答案 2 :(得分:0)

我正在使用一种更简单的解决方案,以避免对url等可变参数使用多个接口。

    @FeignClient(name = "service.name", url = "${app.feign.clients.url}")
    public interface YourClient{}

application- {profile} .properties

app.feign.clients.url=http://localhost:9999