Commit 2acd353c by Spencer Gibb

Allow Feign Hystrix support to be disabled.

fixes gh-717
parent 456f2c0a
......@@ -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;
......@@ -98,6 +100,12 @@ public class FeignClientOverrideDefaultsTests {
}
@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));
Request.Options options = factory.getInstance("bar", 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 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment