From b3acc1390c6571ee9970ab6d0cb10c53f95f70c4 Mon Sep 17 00:00:00 2001 From: saga Date: Wed, 3 Jan 2018 03:24:54 +0800 Subject: [PATCH] Add check to prevent StackOverflowError (#2580) --- .../netflix/feign/FeignClientsRegistrar.java | 10 ++++- .../feign/FeignClientsRegistrarTests.java | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrar.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrar.java index a60b5a4c..9d2fecb7 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrar.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrar.java @@ -17,7 +17,6 @@ package org.springframework.cloud.netflix.feign; import java.io.IOException; -import java.lang.annotation.Annotation; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; @@ -36,7 +35,6 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.EnvironmentAware; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; @@ -208,6 +206,14 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, AnnotationAttributes annotation = AnnotationAttributes.fromMap(attributes); // This blows up if an aliased property is overspecified // FIXME annotation.getAliasedString("name", FeignClient.class, null); + Assert.isTrue( + !annotation.getClass("fallback").isInterface(), + "Fallback class must implement the interface annotated by @FeignClient" + ); + Assert.isTrue( + !annotation.getClass("fallbackFactory").isInterface(), + "Fallback factory must produce instances of fallback classes that implement the interface annotated by @FeignClient" + ); } /* for testing */ String getName(Map attributes) { diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrarTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrarTests.java index 5387f601..e8280449 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrarTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrarTests.java @@ -20,13 +20,19 @@ package org.springframework.cloud.netflix.feign; import java.util.Collections; import org.junit.Test; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Configuration; import org.springframework.mock.env.MockEnvironment; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; /** * @author Spencer Gibb + * @author Gang Li */ public class FeignClientsRegistrarTests { @@ -74,4 +80,42 @@ public class FeignClientsRegistrarTests { registrar.setEnvironment(new MockEnvironment()); return registrar.getName(Collections.singletonMap("name", name)); } + + + @Test(expected = IllegalArgumentException.class) + public void testFallback() { + new AnnotationConfigApplicationContext(FallbackTestConfig.class); + } + + @Test(expected = IllegalArgumentException.class) + public void testFallbackFactory() { + new AnnotationConfigApplicationContext(FallbackFactoryTestConfig.class); + } + + @Configuration + @EnableAutoConfiguration + @EnableFeignClients(clients = { FeignClientsRegistrarTests.FallbackClient.class}) + protected static class FallbackTestConfig { + + } + + @FeignClient(name = "fallbackTestClient", url = "http://localhost:8080/", fallback = FallbackClient.class) + protected interface FallbackClient { + @RequestMapping(method = RequestMethod.GET, value = "/hello") + String fallbackTest(); + } + + @Configuration + @EnableAutoConfiguration + @EnableFeignClients(clients = { FeignClientsRegistrarTests.FallbackFactoryClient.class}) + protected static class FallbackFactoryTestConfig { + + } + + @FeignClient(name = "fallbackFactoryTestClient", url = "http://localhost:8081/", fallbackFactory = FallbackFactoryClient.class) + protected interface FallbackFactoryClient { + @RequestMapping(method = RequestMethod.GET, value = "/hello") + String fallbackFactoryTest(); + } + }