I was testing Feign Hystrix Fallbacks.
I followed the document here http://cloud.spring.io/spring-cloud-static/Camden.SR2/#spring-cloud-feign-hystrix-fallback .The code is blew:
@FeignClient(name = "microservice-provider-user", fallbackFactory = FeignClientFallbackFactory.class)
public interface UserFeignClient {
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public User findById(@PathVariable("id") Long id);
@Component
static class FeignClientFallbackFactory implements FallbackFactory<UserFeignClient> {
private static final Logger LOGGER = LoggerFactory.getLogger(FeignClientFallbackFactory.class);
@Override
public UserFeignClient create(Throwable cause) {
FeignClientFallbackFactory.LOGGER.info("fallback; reason was: {}, {}", cause.getMessage(), cause);
return new UserFeignClient() {
@Override
public User findById(Long id) {
return new User();
}
};
}
}
}
I found that a exception would happen when I start application:
java.lang.RuntimeException: null
at org.springframework.cloud.netflix.feign.HystrixTargeter.targetWithFallbackFactory(HystrixTargeter.java:59) [spring-cloud-netflix-core-1.2.2.RELEASE.jar:1.2.2.RELEASE]
at org.springframework.cloud.netflix.feign.HystrixTargeter.target(HystrixTargeter.java:45) [spring-cloud-netflix-core-1.2.2.RELEASE.jar:1.2.2.RELEASE]
at org.springframework.cloud.netflix.feign.FeignClientFactoryBean.loadBalance(FeignClientFactoryBean.java:146) [spring-cloud-netflix-core-1.2.2.RELEASE.jar:1.2.2.RELEASE]
at org.springframework.cloud.netflix.feign.FeignClientFactoryBean.getObject(FeignClientFactoryBean.java:167) [spring-cloud-netflix-core-1.2.2.RELEASE.jar:1.2.2.RELEASE]
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168) [spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103) [spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1606) [spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:254) [spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) [spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
When I tracked into the class org.springframework.cloud.netflix.feign.HystrixTargeter ,I found that
private <T> T targetWithFallbackFactory(String feignClientName, FeignContext context,
Target.HardCodedTarget<T> target,
HystrixFeign.Builder builder,
Class<?> fallbackFactoryClass) {
FallbackFactory<? extends T> fallbackFactory = (FallbackFactory<? extends T>)
getFromContext("fallbackFactory", feignClientName, context, fallbackFactoryClass, FallbackFactory.class);
/* We take a sample fallback from the fallback factory to check if it returns a fallback
that is compatible with the annotated feign interface. */
Object exampleFallback = fallbackFactory.create(new RuntimeException());
....
It seems that this line of code cause the exception:
Object exampleFallback = fallbackFactory.create(new RuntimeException());
So,the question is:
-
Have I found the right reason of the exception?
-
Should I just ignore the exception when application starts up?
- Is there any way to avoid the exception?
CODE is here https://github.com/eacdy/microservice-consumer-movie-feign-hystrix-fallback-factory
Comment From: ryanjbaxter
The reason you see the exception is because of your logger call https://github.com/eacdy/microservice-consumer-movie-feign-hystrix-fallback-factory/blob/master/src/main/java/com/itmuch/cloud/study/user/feign/UserFeignClient.java#L36
Comment From: eacdy
@ryanjbaxter
I see it is because of my logger call, but I'm wondering why it comes into the method public UserFeignClient create(Throwable cause) when the application starts up.
Comment From: ryanjbaxter
See @bpicode's comment here https://github.com/spring-cloud/spring-cloud-netflix/pull/1373#discussion_r81830003
Comment From: bpicode
Is it an option for you to move the log statement inside the fallback? Schematically,
@Override
public UserFeignClient create(Throwable cause) {
return new UserFeignClient() {
@Override
public User findById(Long id) {
FeignClientFallbackFactory.LOGGER.info("fallback; reason was: {}, {}", cause.getMessage(), cause);
return new User();
}
};
}
Comment From: eacdy
@bpicode Thank you very much, it works.
Comment From: chenjians
我启动的时候不进 public DemoRemoteClient create(Throwable throwable) {} 大佬解答下