Allow Feign Hystrix support to be disabled.
fixes gh-717
This commit is contained in:
@@ -806,6 +806,7 @@ Spring Cloud Netflix provides the following beans by default for feign (`BeanTyp
|
||||
* `Encoder` feignEncoder: `SpringEncoder`
|
||||
* `Logger` feignLogger: `Slf4jLogger`
|
||||
* `Contract` feignContract: `SpringMvcContract`
|
||||
* `Feign.Builder` feignBuilder: `HystrixFeign.Builder`
|
||||
|
||||
Spring Cloud Netflix _does not_ provide the following beans by default for feign, but still looks up beans of these types from the application context to create the feign client:
|
||||
|
||||
@@ -837,6 +838,27 @@ This replaces the `SpringMvcContract` with `feign.Contract.Default` and adds a `
|
||||
|
||||
Default configurations can be specified in the `@EnableFeignClients` attribute `defaultConfiguration` in a similar manner as described above. The difference is that this configuration will apply to _all_ feign clients.
|
||||
|
||||
[[spring-cloud-feign-hystrix]]
|
||||
=== Feign Hystrix Support
|
||||
|
||||
If Hystrix is on the classpath, by default Feign will wrap all methods with a circuit breaker. Returning a `com.netflix.hystrix.HystrixCommand` is also available. This lets you use reactive patterns (with a call to `.toObservable()` or `.observe()` or asynchronous use (with a call to `.queue()`).
|
||||
|
||||
To disable Hystrix support for Feign, set `feign.hystrix.enabled=false`.
|
||||
|
||||
To disable Hystrix support on a per-client basis create a vanilla `Feign.Builder` with the "prototype" scope, e.g.:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@Configuration
|
||||
public class FooConfiguration {
|
||||
@Bean
|
||||
@Scope("prototype")
|
||||
public Feign.Builder feignBuilder() {
|
||||
return Feign.builder();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
[[spring-cloud-feign-inheritance]]
|
||||
=== Feign Inheritance Support
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean, A
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
Feign.Builder builder = HystrixFeign.builder()
|
||||
Feign.Builder builder = get(factory, Feign.Builder.class)
|
||||
// required values
|
||||
.logger(logger)
|
||||
.encoder(get(factory, Encoder.class))
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
|
||||
import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;
|
||||
import org.springframework.cloud.netflix.feign.support.SpringDecoder;
|
||||
@@ -31,12 +32,17 @@ import org.springframework.cloud.netflix.feign.support.SpringEncoder;
|
||||
import org.springframework.cloud.netflix.feign.support.SpringMvcContract;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
|
||||
import com.netflix.hystrix.HystrixCommand;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Contract;
|
||||
import feign.Feign;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.httpclient.ApacheHttpClient;
|
||||
import feign.hystrix.HystrixFeign;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -68,6 +74,23 @@ public class FeignClientsConfiguration {
|
||||
return new SpringMvcContract(parameterProcessors);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope("prototype")
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnClass(HystrixCommand.class)
|
||||
@ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = true)
|
||||
public Feign.Builder feignHystrixBuilder() {
|
||||
return HystrixFeign.builder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope("prototype")
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = false, havingValue = "false")
|
||||
public Feign.Builder feignBuilder() {
|
||||
return Feign.builder();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(ApacheHttpClient.class)
|
||||
protected static class HttpClientConfiguration {
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import feign.Contract;
|
||||
import feign.Feign;
|
||||
import feign.Logger;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.hystrix.HystrixFeign;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -70,6 +72,11 @@ public class EnableFeignClientsTests {
|
||||
SpringMvcContract.class.cast(this.factory.getInstance("foo", Contract.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void builderDefaultCorrect() {
|
||||
HystrixFeign.Builder.class.cast(this.factory.getInstance("foo", Feign.Builder.class));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({ PropertyPlaceholderAutoConfiguration.class,
|
||||
ArchaiusAutoConfiguration.class, FeignAutoConfiguration.class })
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cloud.netflix.feign;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import feign.Contract;
|
||||
import feign.Feign;
|
||||
import feign.Logger;
|
||||
import feign.Request;
|
||||
import feign.RequestInterceptor;
|
||||
@@ -27,6 +28,7 @@ import feign.auth.BasicAuthRequestInterceptor;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.codec.ErrorDecoder;
|
||||
import feign.hystrix.HystrixFeign;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -97,6 +99,12 @@ public class FeignClientOverrideDefaultsTests {
|
||||
ErrorDecoder.Default.class.cast(factory.getInstance("bar", ErrorDecoder.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overrideBuilder() {
|
||||
Feign.Builder.class.cast(factory.getInstance("foo", Feign.Builder.class));
|
||||
HystrixFeign.Builder.class.cast(factory.getInstance("bar", Feign.Builder.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overrideRequestOptions() {
|
||||
assertNull(factory.getInstance("foo", Request.Options.class));
|
||||
@@ -145,6 +153,11 @@ public class FeignClientOverrideDefaultsTests {
|
||||
public Contract feignContract() {
|
||||
return new Contract.Default();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Feign.Builder feignBuilder() {
|
||||
return Feign.builder();
|
||||
}
|
||||
}
|
||||
|
||||
@FeignClient(value = "bar", configuration = BarConfiguration.class)
|
||||
|
||||
@@ -62,7 +62,8 @@ import lombok.NoArgsConstructor;
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = FeignHttpClientTests.Application.class)
|
||||
@WebAppConfiguration
|
||||
@IntegrationTest({ "server.port=0", "spring.application.name=feignclienttest" })
|
||||
@IntegrationTest({ "server.port=0", "spring.application.name=feignclienttest",
|
||||
"feign.hystrix.enabled=false" })
|
||||
@DirtiesContext
|
||||
public class FeignHttpClientTests {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user