diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java index 58aec375..53e05b5c 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java @@ -66,6 +66,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.context.support.GenericApplicationContext; import org.springframework.data.domain.Page; import org.springframework.data.domain.Sort; import org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2AuthorizedClientManager; @@ -111,7 +112,7 @@ public class FeignAutoConfiguration { } @Bean - static FeignChildContextInitializer feignChildContextInitializer(ApplicationContext parentContext, + static FeignChildContextInitializer feignChildContextInitializer(GenericApplicationContext parentContext, FeignClientFactory feignClientFactory) { return new FeignChildContextInitializer(parentContext, feignClientFactory); } diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactoryBean.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactoryBean.java index 195bdbef..96589dbf 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactoryBean.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactoryBean.java @@ -113,6 +113,8 @@ public class FeignClientFactoryBean private final List additionalCustomizers = new ArrayList<>(); + private String[] qualifiers = new String[] {}; + @Override public void afterPropertiesSet() { Assert.hasText(contextId, "Context id must be set"); @@ -600,6 +602,14 @@ public class FeignClientFactoryBean this.refreshableClient = refreshableClient; } + public String[] getQualifiers() { + return qualifiers; + } + + public void setQualifiers(String[] qualifiers) { + this.qualifiers = qualifiers; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientSpecification.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientSpecification.java index 9477d568..0fcd59ac 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientSpecification.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientSpecification.java @@ -29,13 +29,16 @@ public class FeignClientSpecification implements NamedContextFactory.Specificati private String name; + private String className; + private Class[] configuration; - FeignClientSpecification() { + public FeignClientSpecification() { } - public FeignClientSpecification(String name, Class[] configuration) { + public FeignClientSpecification(String name, String className, Class[] configuration) { this.name = name; + this.className = className; this.configuration = configuration; } @@ -47,6 +50,14 @@ public class FeignClientSpecification implements NamedContextFactory.Specificati this.name = name; } + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + public Class[] getConfiguration() { return this.configuration; } @@ -57,25 +68,25 @@ public class FeignClientSpecification implements NamedContextFactory.Specificati @Override public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - FeignClientSpecification that = (FeignClientSpecification) o; - return Objects.equals(name, that.name) && Arrays.equals(configuration, that.configuration); + if (this == o) return true; + if (!(o instanceof FeignClientSpecification that)) return false; + return Objects.equals(name, that.name) && Objects.equals(className, that.className) && Arrays.equals(configuration, that.configuration); } @Override public int hashCode() { - return Objects.hash(name, Arrays.hashCode(configuration)); + int result = Objects.hash(name, className); + result = 31 * result + Arrays.hashCode(configuration); + return result; } + @Override public String toString() { - return new StringBuilder("FeignClientSpecification{").append("name='").append(name).append("', ") - .append("configuration=").append(Arrays.toString(configuration)).append("}").toString(); + return "FeignClientSpecification{" + "name='" + + name + "', " + + "className='" + className + "', " + + "configuration=" + Arrays.toString(configuration) + "}"; } } diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientsRegistrar.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientsRegistrar.java index f423c801..76bbbc1b 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientsRegistrar.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientsRegistrar.java @@ -162,12 +162,11 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo else { name = "default." + metadata.getClassName(); } - registerClientConfiguration(registry, name, defaultAttrs.get("defaultConfiguration")); + registerClientConfiguration(registry, name, "default", defaultAttrs.get("defaultConfiguration")); } } public void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { - LinkedHashSet candidateComponents = new LinkedHashSet<>(); Map attrs = metadata.getAnnotationAttributes(EnableFeignClients.class.getName()); final Class[] clients = attrs == null ? null : (Class[]) attrs.get("clients"); @@ -193,10 +192,11 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface"); Map attributes = annotationMetadata - .getAnnotationAttributes(FeignClient.class.getCanonicalName()); + .getAnnotationAttributes(FeignClient.class.getCanonicalName()); String name = getClientName(attributes); - registerClientConfiguration(registry, name, attributes.get("configuration")); + String className = annotationMetadata.getClassName(); + registerClientConfiguration(registry, name, className, attributes.get("configuration")); registerFeignClient(registry, annotationMetadata, attributes); } @@ -209,7 +209,7 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo String className = annotationMetadata.getClassName(); Class clazz = ClassUtils.resolveClassName(className, null); ConfigurableBeanFactory beanFactory = registry instanceof ConfigurableBeanFactory - ? (ConfigurableBeanFactory) registry : null; + ? (ConfigurableBeanFactory) registry : null; String contextId = getContextId(beanFactory, attributes); String name = getName(attributes); FeignClientFactoryBean factoryBean = new FeignClientFactoryBean(); @@ -218,6 +218,14 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo factoryBean.setContextId(contextId); factoryBean.setType(clazz); factoryBean.setRefreshableClient(isClientRefreshEnabled()); + + String[] qualifiers = getQualifiers(attributes); + if (ObjectUtils.isEmpty(qualifiers)) { + qualifiers = new String[] {contextId + "FeignClient"}; + } + // This is done so that there's a way to retrieve qualifiers while generating AOT code + factoryBean.setQualifiers(qualifiers); + BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(clazz, () -> { factoryBean.setUrl(getUrl(beanFactory, attributes)); factoryBean.setPath(getPath(beanFactory, attributes)); @@ -225,7 +233,7 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo Object fallback = attributes.get("fallback"); if (fallback != null) { factoryBean.setFallback(fallback instanceof Class ? (Class) fallback - : ClassUtils.resolveClassName(fallback.toString(), null)); + : ClassUtils.resolveClassName(fallback.toString(), null)); } Object fallbackFactory = attributes.get("fallbackFactory"); if (fallbackFactory != null) { @@ -247,11 +255,6 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo beanDefinition.setPrimary(primary); - String[] qualifiers = getQualifiers(attributes); - if (ObjectUtils.isEmpty(qualifiers)) { - qualifiers = new String[] { contextId + "FeignClient" }; - } - BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className, qualifiers); BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry); @@ -407,12 +410,13 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo "Either 'name' or 'value' must be provided in @" + FeignClient.class.getSimpleName()); } - private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name, Object configuration) { + private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name, Object className, Object configuration) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(FeignClientSpecification.class); builder.addConstructorArgValue(name); + builder.addConstructorArgValue(className); builder.addConstructorArgValue(configuration); registry.registerBeanDefinition(name + "." + FeignClientSpecification.class.getSimpleName(), - builder.getBeanDefinition()); + builder.getBeanDefinition()); } @Override diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/aot/FeignChildContextInitializer.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/aot/FeignChildContextInitializer.java index 7eb23c2d..3ab4845e 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/aot/FeignChildContextInitializer.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/aot/FeignChildContextInitializer.java @@ -4,6 +4,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; @@ -12,21 +13,33 @@ import javax.lang.model.element.Modifier; import org.springframework.aot.generate.GeneratedMethod; import org.springframework.aot.generate.GenerationContext; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.aot.BeanRegistrationAotContribution; import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor; import org.springframework.beans.factory.aot.BeanRegistrationCode; +import org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanDefinitionHolder; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +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.beans.factory.support.GenericBeanDefinition; import org.springframework.beans.factory.support.RegisteredBean; import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.cloud.openfeign.FeignClientFactory; +import org.springframework.cloud.openfeign.FeignClientFactoryBean; import org.springframework.cloud.openfeign.FeignClientSpecification; -import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.aot.ApplicationContextAotGenerator; import org.springframework.context.support.GenericApplicationContext; import org.springframework.javapoet.ClassName; +import org.springframework.javapoet.MethodSpec; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; /** * A {@link BeanRegistrationAotProcessor} that creates an {@link BeanRegistrationAotContribution} for @@ -35,28 +48,32 @@ import org.springframework.util.Assert; * @author Olga Maciaszek-Sharma * @since 4.0.0 */ -public class FeignChildContextInitializer implements BeanRegistrationAotProcessor, ApplicationListener { +public class FeignChildContextInitializer implements BeanRegistrationAotProcessor, ApplicationListener, + BeanRegistrationExcludeFilter { - private final ApplicationContext applicationContext; + private final GenericApplicationContext context; private final FeignClientFactory feignClientFactory; private final Map> applicationContextInitializers; - public FeignChildContextInitializer(ApplicationContext applicationContext, FeignClientFactory feignClientFactory) { - this(applicationContext, feignClientFactory, new HashMap<>()); + private final Map feignClientBeanDefinitions; + + public FeignChildContextInitializer(GenericApplicationContext context, FeignClientFactory feignClientFactory) { + this(context, feignClientFactory, new HashMap<>()); } - public FeignChildContextInitializer(ApplicationContext applicationContext, FeignClientFactory feignClientFactory, Map> applicationContextInitializers) { - this.applicationContext = applicationContext; + public FeignChildContextInitializer(GenericApplicationContext context, FeignClientFactory feignClientFactory, Map> applicationContextInitializers) { + this.context = context; this.feignClientFactory = feignClientFactory; this.applicationContextInitializers = applicationContextInitializers; + feignClientBeanDefinitions = getFeignClientClassNames(); } @Override public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) { - Assert.isInstanceOf(ConfigurableApplicationContext.class, applicationContext); - ConfigurableApplicationContext context = ((ConfigurableApplicationContext) applicationContext); + Assert.isInstanceOf(ConfigurableApplicationContext.class, context); + ConfigurableApplicationContext context = this.context; BeanFactory applicationBeanFactory = context.getBeanFactory(); if (!(registeredBean.getBeanClass().equals(getClass()) && registeredBean.getBeanFactory().equals(applicationBeanFactory))) { @@ -66,7 +83,7 @@ public class FeignChildContextInitializer implements BeanRegistrationAotProcesso Map childContextAotContributions = contextIds.stream() .map(contextId -> Map.entry(contextId, buildChildContext(contextId))) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - return new AotContribution(childContextAotContributions); + return new AotContribution(childContextAotContributions, feignClientBeanDefinitions); } private GenericApplicationContext buildChildContext(String contextId) { @@ -89,13 +106,13 @@ public class FeignChildContextInitializer implements BeanRegistrationAotProcesso .forEach(contextId -> convertedInitializers.put(contextId, (ApplicationContextInitializer) applicationContextInitializers .get(contextId))); - return new FeignChildContextInitializer(applicationContext, feignClientFactory, + return new FeignChildContextInitializer(context, feignClientFactory, convertedInitializers); } @Override public void onApplicationEvent(WebServerInitializedEvent event) { - if (applicationContext.equals(event.getApplicationContext())) { + if (context.equals(event.getApplicationContext())) { applicationContextInitializers.keySet().forEach(contextId -> { GenericApplicationContext childContext = feignClientFactory.buildContext(contextId); applicationContextInitializers.get(contextId).initialize(childContext); @@ -110,15 +127,33 @@ public class FeignChildContextInitializer implements BeanRegistrationAotProcesso return false; } + @Override + public boolean isExcludedFromAotProcessing(RegisteredBean registeredBean) { + return feignClientBeanDefinitions + .containsKey(registeredBean.getBeanClass().getName()); + } + + private Map getFeignClientClassNames() { + Map configurations = feignClientFactory.getConfigurations(); + return configurations.values().stream() + .map(FeignClientSpecification::getClassName) + .filter(Objects::nonNull) + .filter(className -> !className.equals("default")) + .map(className -> Map.entry(className, context.getBeanDefinition(className))) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + private static class AotContribution implements BeanRegistrationAotContribution { private final Map childContexts; + private final Map feignClientBeanDefinitions; - public AotContribution(Map childContexts) { + public AotContribution(Map childContexts, Map feignClientBeanDefinitions) { this.childContexts = childContexts.entrySet().stream() .filter(entry -> entry.getValue() != null) .map(entry -> Map.entry(entry.getKey(), entry.getValue())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + this.feignClientBeanDefinitions = feignClientBeanDefinitions; } @Override @@ -149,6 +184,68 @@ public class FeignChildContextInitializer implements BeanRegistrationAotProcesso method.addStatement("return instance.withApplicationContextInitializers(initializers)"); }); beanRegistrationCode.addInstancePostProcessor(postProcessorMethod.toMethodReference()); + + // TODO: ensure the methods are called + feignClientBeanDefinitions.values().forEach(beanDefinition -> { + // TODO: handle problem retrieving + Assert.notNull(beanDefinition, "beanDefinition cannot be null"); + Assert.isInstanceOf(GenericBeanDefinition.class, beanDefinition); + GenericBeanDefinition registeredBeanDefinition = (GenericBeanDefinition) beanDefinition; + Object factoryBeanObject = registeredBeanDefinition.getAttribute("feignClientsRegistrarFactoryBean"); + Assert.isInstanceOf(FeignClientFactoryBean.class, factoryBeanObject); + FeignClientFactoryBean factoryBean = (FeignClientFactoryBean) factoryBeanObject; + Assert.notNull(factoryBean, "factoryBean cannot be null"); + generationContext.getGeneratedClasses() + // FIXME: correct generation context + .getOrAddForFeatureComponent(registeredBeanDefinition.getBeanClassName(), generatedInitializerClassNames.get(factoryBean.getContextId()), type -> { + type.addMethod(buildMethodSpec(factoryBean, registeredBeanDefinition)); + } + ); + }); + } + + + // TODO: verify all factory bean method values from registrar! + private MethodSpec buildMethodSpec(FeignClientFactoryBean registeredFactoryBean, GenericBeanDefinition registeredBeanDefinition) { + String qualifiers = "{\"" + String.join("\",\"", registeredFactoryBean.getQualifiers()) + "\"}"; + return MethodSpec.methodBuilder("feignClientRegistration") + .addJavadoc("registerFeignClient") + .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .addParameter(BeanDefinitionRegistry.class, "registry") + .addStatement("Class clazz = $T.resolveClassName(\"$L\", null)", ClassUtils.class, registeredBeanDefinition.getBeanClassName()) + .addStatement("$T beanFactory = registry instanceof $T ? ($T) registry : null", + ConfigurableBeanFactory.class, ConfigurableBeanFactory.class, ConfigurableBeanFactory.class) + .addStatement("$T factoryBean = new $T()", FeignClientFactoryBean.class, FeignClientFactoryBean.class) + .addStatement("factoryBean.setBeanFactory(beanFactory)") + .addStatement("factoryBean.setName(\"$L\")", registeredFactoryBean.getName()) + .addStatement("factoryBean.setContextId(\"$L\")", registeredFactoryBean.getContextId()) + .addStatement("factoryBean.setType($T.class)", registeredFactoryBean.getType()) + .addStatement("factoryBean.setUrl($L)", registeredFactoryBean.getUrl()) + .addStatement("factoryBean.setPath($L)", registeredFactoryBean.getPath()) + .addStatement("factoryBean.setDismiss404($L)", registeredFactoryBean.isDismiss404()) + .addStatement("factoryBean.setFallback($T.class)", registeredFactoryBean.getFallback()) + .addStatement("factoryBean.setFallbackFactory($T.class)", registeredFactoryBean.getFallbackFactory()) + .addStatement("$T definition = $T.genericBeanDefinition(clazz, () -> factoryBean.getObject())", BeanDefinitionBuilder.class, + BeanDefinitionBuilder.class) + .addStatement("definition.setAutowireMode($L)", registeredBeanDefinition.getAutowireMode()) + .addStatement("definition.setLazyInit($L)", registeredBeanDefinition.getLazyInit()) + .addStatement("$T beanDefinition = definition.getBeanDefinition()", AbstractBeanDefinition.class) + .addStatement("beanDefinition.setAttribute(\"$L\", $T.class)", FactoryBean.OBJECT_TYPE_ATTRIBUTE, registeredFactoryBean.getType()) + .addStatement("beanDefinition.setAttribute(\"feignClientsRegistrarFactoryBean\", factoryBean)") + .addStatement("beanDefinition.setPrimary($L)", registeredBeanDefinition.isPrimary()) + .addStatement("String[] qualifiers = new String[]{}") + .addStatement("$T holder = new $T(beanDefinition, \"$L\", new String[]$L)", BeanDefinitionHolder.class, + BeanDefinitionHolder.class, registeredBeanDefinition.getBeanClassName(), qualifiers) + .addStatement("$T.registerBeanDefinition(holder, registry) ", BeanDefinitionReaderUtils.class) + .build(); + // TODO +// .addStatement("Class beanType = $T.class", Class.forName(feignClientBeanDefinition.getBeanClassName())) +// .addStatement("$T beanDefinition = new $T(beanType)", RootBeanDefinition.class, RootBeanDefinition.class) +// .addStatement("beanDefinition.setLazyInit($L)", feignClientBeanDefinition.isLazyInit()) +// .addStatement("beanDefinition.setInstanceSupplier(($T) registeredBean -> new $T())", InstanceSupplier.class, FeignClientFactoryBean.class) +// .addStatement("return beanDefinition") + + } } diff --git a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientFactoryTest.java b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientFactoryTest.java index 890dca33..08e16e82 100644 --- a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientFactoryTest.java +++ b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientFactoryTest.java @@ -39,15 +39,15 @@ class FeignClientFactoryTest { FeignClientFactory feignClientFactory = new FeignClientFactory(); feignClientFactory.setApplicationContext(parent); - feignClientFactory.setConfigurations(Lists.newArrayList(getSpec("empty", EmptyConfiguration.class))); + feignClientFactory.setConfigurations(Lists.newArrayList(getSpec("empty", null, EmptyConfiguration.class))); Logger.Level level = feignClientFactory.getInstanceWithoutAncestors("empty", Logger.Level.class); assertThat(level).as("Logger was not null").isNull(); } - private FeignClientSpecification getSpec(String name, Class configClass) { - return new FeignClientSpecification(name, new Class[] { configClass }); + private FeignClientSpecification getSpec(String name, String className, Class configClass) { + return new FeignClientSpecification(name, className, new Class[] {configClass}); } @Test @@ -57,7 +57,7 @@ class FeignClientFactoryTest { FeignClientFactory feignClientFactory = new FeignClientFactory(); feignClientFactory.setApplicationContext(parent); - feignClientFactory.setConfigurations(Lists.newArrayList(getSpec("empty", EmptyConfiguration.class))); + feignClientFactory.setConfigurations(Lists.newArrayList(getSpec("empty", null, EmptyConfiguration.class))); Collection interceptors = feignClientFactory .getInstancesWithoutAncestors("empty", RequestInterceptor.class).values(); @@ -72,7 +72,7 @@ class FeignClientFactoryTest { FeignClientFactory feignClientFactory = new FeignClientFactory(); feignClientFactory.setApplicationContext(parent); - feignClientFactory.setConfigurations(Lists.newArrayList(getSpec("demo", DemoConfiguration.class))); + feignClientFactory.setConfigurations(Lists.newArrayList(getSpec("demo", null, DemoConfiguration.class))); Logger.Level level = feignClientFactory.getInstanceWithoutAncestors("demo", Logger.Level.class); @@ -86,7 +86,7 @@ class FeignClientFactoryTest { FeignClientFactory feignClientFactory = new FeignClientFactory(); feignClientFactory.setApplicationContext(parent); - feignClientFactory.setConfigurations(Lists.newArrayList(getSpec("demo", DemoConfiguration.class))); + feignClientFactory.setConfigurations(Lists.newArrayList(getSpec("demo", null, DemoConfiguration.class))); Collection interceptors = feignClientFactory .getInstancesWithoutAncestors("demo", RequestInterceptor.class).values(); diff --git a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientFactoryTests.java b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientFactoryTests.java index 1f238731..ecc0937a 100644 --- a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientFactoryTests.java +++ b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientFactoryTests.java @@ -54,7 +54,7 @@ public class FeignClientFactoryTests { parent.refresh(); FeignClientFactory context = new FeignClientFactory(); context.setApplicationContext(parent); - context.setConfigurations(Arrays.asList(getSpec("foo", FooConfig.class), getSpec("bar", BarConfig.class))); + context.setConfigurations(Arrays.asList(getSpec("foo", null, FooConfig.class), getSpec("bar", null, BarConfig.class))); Foo foo = context.getInstance("foo", Foo.class); assertThat(foo).as("foo was null").isNotNull(); @@ -77,14 +77,14 @@ public class FeignClientFactoryTests { Proxy target = context.getBean(FeignClientFactoryBean.class).getTarget(); Object invocationHandler = ReflectionTestUtils.getField(target, "h"); Map dispatch = (Map) ReflectionTestUtils - .getField(invocationHandler, "dispatch"); + .getField(invocationHandler, "dispatch"); Method key = new ArrayList<>(dispatch.keySet()).get(0); Object client = ReflectionTestUtils.getField(dispatch.get(key), "client"); assertThat(client).isInstanceOf(Client.Default.class); } - private FeignClientSpecification getSpec(String name, Class configClass) { - return new FeignClientSpecification(name, new Class[] { configClass }); + private FeignClientSpecification getSpec(String name, String className, Class configClass) { + return new FeignClientSpecification(name, className, new Class[] {configClass}); } interface TestType { @@ -106,7 +106,7 @@ public class FeignClientFactoryTests { FeignClientFactory feignContext() { FeignClientFactory feignClientFactory = new FeignClientFactory(); feignClientFactory.setConfigurations(Collections.singletonList( - new FeignClientSpecification("test", new Class[] { LoadBalancerAutoConfiguration.class }))); + new FeignClientSpecification("test", null, new Class[] {LoadBalancerAutoConfiguration.class}))); return feignClientFactory; } diff --git a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/aot/FeignChildContextInitializerTests.java b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/aot/FeignChildContextInitializerTests.java index 1807bb59..fb38e49a 100644 --- a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/aot/FeignChildContextInitializerTests.java +++ b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/aot/FeignChildContextInitializerTests.java @@ -40,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Olga Maciaszek-Sharma */ @ExtendWith(OutputCaptureExtension.class) -class FeignChildContextInitializerTests { +public class FeignChildContextInitializerTests { private static final Log LOG = LogFactory.getLog(FeignChildContextInitializerTests.class);