From b7c43f02c1c14c6910b15b48744fdd7c6fa44b88 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 30 Nov 2022 17:11:01 +0100 Subject: [PATCH] Fix checkstyle. Reformat. --- .../openfeign/FeignAutoConfiguration.java | 8 +- .../cloud/openfeign/FeignClientFactory.java | 14 +- .../openfeign/FeignClientFactoryBean.java | 2 +- .../openfeign/FeignClientSpecification.java | 18 +-- .../openfeign/FeignClientsRegistrar.java | 54 ++++--- .../aot/FeignChildContextInitializer.java | 74 +++++----- ...BeanFactoryInitializationAotProcessor.java | 132 +++++++++++------- .../openfeign/FeignClientFactoryTest.java | 2 +- .../openfeign/FeignClientFactoryTests.java | 9 +- .../cloud/openfeign/aot/FeignAotTests.java | 41 ++++-- 10 files changed, 203 insertions(+), 151 deletions(-) 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 e796b4ad..eff4d407 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 @@ -113,13 +113,13 @@ public class FeignAutoConfiguration { @Bean static FeignChildContextInitializer feignChildContextInitializer(GenericApplicationContext parentContext, - FeignClientFactory feignClientFactory) { + FeignClientFactory feignClientFactory) { return new FeignChildContextInitializer(parentContext, feignClientFactory); } @Bean - static FeignClientBeanFactoryInitializationAotProcessor feignClientBeanFactoryInitializationCodeGenerator(GenericApplicationContext applicationContext, - FeignClientFactory feignClientFactory) { + static FeignClientBeanFactoryInitializationAotProcessor feignClientBeanFactoryInitializationCodeGenerator( + GenericApplicationContext applicationContext, FeignClientFactory feignClientFactory) { return new FeignClientBeanFactoryInitializationAotProcessor(applicationContext, feignClientFactory); } @@ -131,7 +131,7 @@ public class FeignAutoConfiguration { } @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({Module.class, Page.class, Sort.class}) + @ConditionalOnClass({ Module.class, Page.class, Sort.class }) @ConditionalOnProperty(value = "spring.cloud.openfeign.autoconfiguration.jackson.enabled", havingValue = "true", matchIfMissing = true) protected static class FeignJacksonConfiguration { diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactory.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactory.java index b82e91dc..177d6a73 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactory.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactory.java @@ -44,7 +44,8 @@ public class FeignClientFactory extends NamedContextFactory()); } - public FeignClientFactory(Map> applicationContextInitializers) { + public FeignClientFactory( + Map> applicationContextInitializers) { super(FeignClientsConfiguration.class, "spring.cloud.openfeign", "spring.cloud.openfeign.client.name"); this.applicationContextInitializers = applicationContextInitializers; } @@ -69,13 +70,12 @@ public class FeignClientFactory extends NamedContextFactory applicationContextInitializers) { + public FeignClientFactory withApplicationContextInitializers(Map applicationContextInitializers) { Map> convertedInitializers = new HashMap<>(); applicationContextInitializers.keySet() - .forEach(contextId -> convertedInitializers.put(contextId, - (ApplicationContextInitializer) applicationContextInitializers - .get(contextId))); + .forEach(contextId -> convertedInitializers.put(contextId, + (ApplicationContextInitializer) applicationContextInitializers + .get(contextId))); return new FeignClientFactory(convertedInitializers); } @@ -89,5 +89,5 @@ public class FeignClientFactory extends NamedContextFactory(); } -} +} 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 66825b04..1b5792b2 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 @@ -419,7 +419,7 @@ public class FeignClientFactoryBean @SuppressWarnings("unchecked") T getTarget() { FeignClientFactory feignClientFactory = beanFactory != null ? beanFactory.getBean(FeignClientFactory.class) - : applicationContext.getBean(FeignClientFactory.class); + : applicationContext.getBean(FeignClientFactory.class); feignClientFactory.initializeChildContexts(); Feign.Builder builder = feign(feignClientFactory); if (!StringUtils.hasText(url) && !isUrlAvailableInConfig(contextId)) { 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 0fcd59ac..6a8abd82 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 @@ -68,9 +68,14 @@ public class FeignClientSpecification implements NamedContextFactory.Specificati @Override public boolean equals(Object o) { - 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); + 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 @@ -80,13 +85,10 @@ public class FeignClientSpecification implements NamedContextFactory.Specificati return result; } - @Override public String toString() { - return "FeignClientSpecification{" + "name='" - + name + "', " - + "className='" + className + "', " - + "configuration=" + Arrays.toString(configuration) + "}"; + 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 012e51a8..39ccf2c6 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 @@ -192,7 +192,7 @@ 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); String className = annotationMetadata.getClassName(); @@ -203,13 +203,12 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo } } - @SuppressWarnings("unchecked") private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata, - Map attributes) { + Map attributes) { String className = annotationMetadata.getClassName(); // TODO: document change and correct AOT and contract usage - if (String.valueOf(false) - .equals(environment.getProperty("spring.cloud.openfeign.lazy-attributes-resolution", String.valueOf(false)))) { + if (String.valueOf(false).equals( + environment.getProperty("spring.cloud.openfeign.lazy-attributes-resolution", String.valueOf(false)))) { eagerlyRegisterFeignClientBeanDefinition(className, attributes, registry); } else { @@ -217,11 +216,10 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo } } - private void eagerlyRegisterFeignClientBeanDefinition(String className, Map attributes, BeanDefinitionRegistry registry) { - // TODO: verify with prod method + private void eagerlyRegisterFeignClientBeanDefinition(String className, Map attributes, + BeanDefinitionRegistry registry) { validate(attributes); BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class); - validate(attributes); definition.addPropertyValue("url", getUrl(null, attributes)); definition.addPropertyValue("path", getPath(null, attributes)); String name = getName(attributes); @@ -232,21 +230,22 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo definition.addPropertyValue("dismiss404", Boolean.parseBoolean(String.valueOf(attributes.get("dismiss404")))); Object fallback = attributes.get("fallback"); if (fallback != null) { - definition.addPropertyValue("fallback", (fallback instanceof Class ? fallback - : ClassUtils.resolveClassName(fallback.toString(), null))); + definition.addPropertyValue("fallback", + (fallback instanceof Class ? fallback : ClassUtils.resolveClassName(fallback.toString(), null))); } Object fallbackFactory = attributes.get("fallbackFactory"); if (fallbackFactory != null) { definition.addPropertyValue("fallbackFactory", fallbackFactory instanceof Class ? fallbackFactory - : ClassUtils.resolveClassName(fallbackFactory.toString(), null)); + : ClassUtils.resolveClassName(fallbackFactory.toString(), null)); } definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory")); definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); String[] qualifiers = getQualifiers(attributes); if (ObjectUtils.isEmpty(qualifiers)) { - qualifiers = new String[] {contextId + "FeignClient"}; + qualifiers = new String[] { contextId + "FeignClient" }; } - // This is done so that there's a way to retrieve qualifiers while generating AOT code + // This is done so that there's a way to retrieve qualifiers while generating AOT + // code definition.addPropertyValue("qualifiers", qualifiers); AbstractBeanDefinition beanDefinition = definition.getBeanDefinition(); beanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, className); @@ -259,10 +258,10 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo registerRefreshableBeanDefinition(registry, contextId, RefreshableUrl.class, RefreshableUrlFactoryBean.class); } - private void lazilyRegisterFeignClientBeanDefinition(String className, Map attributes, BeanDefinitionRegistry registry) { - // TODO: verify with prod method + private void lazilyRegisterFeignClientBeanDefinition(String className, Map attributes, + BeanDefinitionRegistry registry) { ConfigurableBeanFactory beanFactory = registry instanceof ConfigurableBeanFactory - ? (ConfigurableBeanFactory) registry : null; + ? (ConfigurableBeanFactory) registry : null; Class clazz = ClassUtils.resolveClassName(className, null); String contextId = getContextId(beanFactory, attributes); String name = getName(attributes); @@ -272,14 +271,6 @@ 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)); @@ -287,18 +278,19 @@ 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) { factoryBean.setFallbackFactory(fallbackFactory instanceof Class ? (Class) fallbackFactory - : ClassUtils.resolveClassName(fallbackFactory.toString(), null)); + : ClassUtils.resolveClassName(fallbackFactory.toString(), null)); } return factoryBean.getObject(); }); definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); definition.setLazyInit(true); validate(attributes); + AbstractBeanDefinition beanDefinition = definition.getBeanDefinition(); beanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, className); beanDefinition.setAttribute("feignClientsRegistrarFactoryBean", factoryBean); @@ -308,6 +300,11 @@ 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); @@ -463,13 +460,14 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLo "Either 'name' or 'value' must be provided in @" + FeignClient.class.getSimpleName()); } - private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name, Object className, 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 8ee3b653..1d3059a0 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 @@ -1,3 +1,19 @@ +/* + * Copyright 2022-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.cloud.openfeign.aot; import java.util.Collection; @@ -26,8 +42,8 @@ import org.springframework.javapoet.ClassName; import org.springframework.util.Assert; /** - * A {@link BeanRegistrationAotProcessor} that creates an {@link BeanRegistrationAotContribution} for - * Feign child contexts. + * A {@link BeanRegistrationAotProcessor} that creates an + * {@link BeanRegistrationAotContribution} for Feign child contexts. * * @author Olga Maciaszek-Sharma * @since 4.0.0 @@ -38,7 +54,6 @@ public class FeignChildContextInitializer implements BeanRegistrationAotProcesso private final FeignClientFactory feignClientFactory; - public FeignChildContextInitializer(ApplicationContext applicationContext, FeignClientFactory feignClientFactory) { this.applicationContext = applicationContext; this.feignClientFactory = feignClientFactory; @@ -50,13 +65,13 @@ public class FeignChildContextInitializer implements BeanRegistrationAotProcesso ConfigurableApplicationContext context = ((ConfigurableApplicationContext) applicationContext); BeanFactory applicationBeanFactory = context.getBeanFactory(); if (!((registeredBean.getBeanClass().equals(FeignClientFactory.class)) - && registeredBean.getBeanFactory().equals(applicationBeanFactory))) { + && registeredBean.getBeanFactory().equals(applicationBeanFactory))) { return null; } Set contextIds = new HashSet<>(getContextIdsFromConfig()); Map childContextAotContributions = contextIds.stream() - .map(contextId -> Map.entry(contextId, buildChildContext(contextId))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + .map(contextId -> Map.entry(contextId, buildChildContext(contextId))) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); return new AotContribution(childContextAotContributions); } @@ -68,51 +83,44 @@ public class FeignChildContextInitializer implements BeanRegistrationAotProcesso private Collection getContextIdsFromConfig() { Map configurations = feignClientFactory.getConfigurations(); - return configurations.keySet().stream().filter(key -> !key.startsWith("default.")) - .collect(Collectors.toSet()); + return configurations.keySet().stream().filter(key -> !key.startsWith("default.")).collect(Collectors.toSet()); } - private static class AotContribution implements BeanRegistrationAotContribution { private final Map childContexts; - public AotContribution(Map childContexts) { - 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)); + AotContribution(Map childContexts) { + 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)); } @Override public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) { - Map generatedInitializerClassNames = childContexts.entrySet() - .stream() - .map(entry -> { - String name = entry.getValue().getDisplayName(); - name = name.replaceAll("[-]", "_"); - GenerationContext childGenerationContext = generationContext.withName(name); - ClassName initializerClassName = new ApplicationContextAotGenerator() + Map generatedInitializerClassNames = childContexts.entrySet().stream().map(entry -> { + String name = entry.getValue().getDisplayName(); + name = name.replaceAll("[-]", "_"); + GenerationContext childGenerationContext = generationContext.withName(name); + ClassName initializerClassName = new ApplicationContextAotGenerator() .processAheadOfTime(entry.getValue(), childGenerationContext); - return Map.entry(entry.getKey(), initializerClassName); - }) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + return Map.entry(entry.getKey(), initializerClassName); + }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); GeneratedMethod postProcessorMethod = beanRegistrationCode.getMethods() - .add("addFeignChildContextInitializer", - method -> { + .add("addFeignChildContextInitializer", method -> { method.addJavadoc("Use AOT child context management initialization") - .addModifiers(Modifier.PRIVATE, Modifier.STATIC) - .addParameter(RegisteredBean.class, "registeredBean") - .addParameter(FeignClientFactory.class, "instance") - .returns(FeignClientFactory.class) - .addStatement("$T initializers = new $T<>()", Map.class, HashMap.class); + .addModifiers(Modifier.PRIVATE, Modifier.STATIC) + .addParameter(RegisteredBean.class, "registeredBean") + .addParameter(FeignClientFactory.class, "instance").returns(FeignClientFactory.class) + .addStatement("$T initializers = new $T<>()", Map.class, HashMap.class); generatedInitializerClassNames.keySet() - .forEach(contextId -> method.addStatement("initializers.put($S, new $L())", contextId, - generatedInitializerClassNames.get(contextId))); + .forEach(contextId -> method.addStatement("initializers.put($S, new $L())", contextId, + generatedInitializerClassNames.get(contextId))); method.addStatement("return instance.withApplicationContextInitializers(initializers)"); }); beanRegistrationCode.addInstancePostProcessor(postProcessorMethod.toMethodReference()); } + } } diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/aot/FeignClientBeanFactoryInitializationAotProcessor.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/aot/FeignClientBeanFactoryInitializationAotProcessor.java index d9512ba6..d219d7db 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/aot/FeignClientBeanFactoryInitializationAotProcessor.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/aot/FeignClientBeanFactoryInitializationAotProcessor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2022-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.cloud.openfeign.aot; import java.util.Map; @@ -37,33 +53,31 @@ import org.springframework.util.ClassUtils; /** * @author Olga Maciaszek-Sharma */ -public class FeignClientBeanFactoryInitializationAotProcessor implements BeanRegistrationExcludeFilter, BeanFactoryInitializationAotProcessor { - +public class FeignClientBeanFactoryInitializationAotProcessor + implements BeanRegistrationExcludeFilter, BeanFactoryInitializationAotProcessor { private final GenericApplicationContext context; private final Map feignClientBeanDefinitions; - public FeignClientBeanFactoryInitializationAotProcessor(GenericApplicationContext context, FeignClientFactory feignClientFactory) { + public FeignClientBeanFactoryInitializationAotProcessor(GenericApplicationContext context, + FeignClientFactory feignClientFactory) { this.context = context; this.feignClientBeanDefinitions = getFeignClientBeanDefinitions(feignClientFactory); } @Override public boolean isExcludedFromAotProcessing(RegisteredBean registeredBean) { - return registeredBean.getBeanClass() - .equals(FeignClientFactoryBean.class) || feignClientBeanDefinitions - .containsKey(registeredBean.getBeanClass().getName()); + return registeredBean.getBeanClass().equals(FeignClientFactoryBean.class) + || feignClientBeanDefinitions.containsKey(registeredBean.getBeanClass().getName()); } private Map getFeignClientBeanDefinitions(FeignClientFactory feignClientFactory) { 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)); + 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)); } @Override @@ -75,7 +89,7 @@ public class FeignClientBeanFactoryInitializationAotProcessor implements BeanReg return new AotContribution(feignClientBeanDefinitions); } - private static class AotContribution implements BeanFactoryInitializationAotContribution { + private static final class AotContribution implements BeanFactoryInitializationAotContribution { private final Map feignClientBeanDefinitions; @@ -84,22 +98,23 @@ public class FeignClientBeanFactoryInitializationAotProcessor implements BeanReg } @Override - public void applyTo(GenerationContext generationContext, BeanFactoryInitializationCode beanFactoryInitializationCode) { - Set feignClientRegistrationMethods = feignClientBeanDefinitions.values() - .stream() - .map(beanDefinition -> { - Assert.notNull(beanDefinition, "beanDefinition cannot be null"); - Assert.isInstanceOf(GenericBeanDefinition.class, beanDefinition); - GenericBeanDefinition registeredBeanDefinition = (GenericBeanDefinition) beanDefinition; - MutablePropertyValues feignClientProperties = registeredBeanDefinition.getPropertyValues(); - return beanFactoryInitializationCode.getMethods() - .add(buildMethodName((String) feignClientProperties.get("type")), - method -> generateFeignClientRegistrationMethod(method, feignClientProperties, registeredBeanDefinition)) - .getName(); - }).collect(Collectors.toSet()); + public void applyTo(GenerationContext generationContext, + BeanFactoryInitializationCode beanFactoryInitializationCode) { + Set feignClientRegistrationMethods = feignClientBeanDefinitions.values().stream() + .map(beanDefinition -> { + Assert.notNull(beanDefinition, "beanDefinition cannot be null"); + Assert.isInstanceOf(GenericBeanDefinition.class, beanDefinition); + GenericBeanDefinition registeredBeanDefinition = (GenericBeanDefinition) beanDefinition; + MutablePropertyValues feignClientProperties = registeredBeanDefinition.getPropertyValues(); + return beanFactoryInitializationCode.getMethods() + .add(buildMethodName((String) feignClientProperties.get("type")), + method -> generateFeignClientRegistrationMethod(method, feignClientProperties, + registeredBeanDefinition)) + .getName(); + }).collect(Collectors.toSet()); MethodReference initializerMethod = beanFactoryInitializationCode.getMethods() - .add("initialize", method -> generateInitializerMethod(method, feignClientRegistrationMethods)) - .toMethodReference(); + .add("initialize", method -> generateInitializerMethod(method, feignClientRegistrationMethods)) + .toMethodReference(); beanFactoryInitializationCode.addInitializer(initializerMethod); } @@ -110,37 +125,48 @@ public class FeignClientBeanFactoryInitializationAotProcessor implements BeanReg private void generateInitializerMethod(MethodSpec.Builder method, Set feignClientRegistrationMethods) { method.addModifiers(Modifier.PUBLIC); method.addParameter(DefaultListableBeanFactory.class, "registry"); - feignClientRegistrationMethods.forEach(feignClientRegistrationMethod -> method.addStatement("$N(registry)", feignClientRegistrationMethod)); + feignClientRegistrationMethods.forEach(feignClientRegistrationMethod -> method.addStatement("$N(registry)", + feignClientRegistrationMethod)); } - private void generateFeignClientRegistrationMethod(MethodSpec.Builder method, MutablePropertyValues feignClientPropertyValues, GenericBeanDefinition registeredBeanDefinition) { + private void generateFeignClientRegistrationMethod(MethodSpec.Builder method, + MutablePropertyValues feignClientPropertyValues, GenericBeanDefinition registeredBeanDefinition) { Object feignQualifiers = feignClientPropertyValues.get("qualifiers"); Assert.notNull(feignQualifiers, "Feign qualifiers cannot be null"); String qualifiers = "{\"" + String.join("\",\"", (String[]) feignQualifiers) + "\"}"; - method - .addJavadoc("register Feign Client: $L", feignClientPropertyValues.get("type")) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .addParameter(BeanDefinitionRegistry.class, "registry") - .addStatement("Class clazz = $T.resolveClassName(\"$L\", null)", ClassUtils.class, feignClientPropertyValues.get("type")) - .addStatement("$T definition = $T.genericBeanDefinition($T.class)", BeanDefinitionBuilder.class, - BeanDefinitionBuilder.class, FeignClientFactoryBean.class) - .addStatement("definition.addPropertyValue(\"name\",\"$L\")", feignClientPropertyValues.get("name")) - .addStatement("definition.addPropertyValue(\"contextId\", \"$L\")", feignClientPropertyValues.get("contextId")) - .addStatement("definition.addPropertyValue(\"type\", clazz)") - .addStatement("definition.addPropertyValue(\"url\", \"$L\")", feignClientPropertyValues.get("url")) - .addStatement("definition.addPropertyValue(\"path\", \"$L\")", feignClientPropertyValues.get("path")) - .addStatement("definition.addPropertyValue(\"dismiss404\", $L)", feignClientPropertyValues.get("dismiss404")) - .addStatement("definition.addPropertyValue(\"fallback\", $T.class)", feignClientPropertyValues.get("fallback")) - .addStatement("definition.addPropertyValue(\"fallbackFactory\", $T.class)", feignClientPropertyValues.get("fallbackFactory")) - .addStatement("definition.setAutowireMode($L)", registeredBeanDefinition.getAutowireMode()) - .addStatement("definition.setLazyInit($L)", registeredBeanDefinition.getLazyInit() != null ? registeredBeanDefinition.getLazyInit() : false) - .addStatement("$T beanDefinition = definition.getBeanDefinition()", AbstractBeanDefinition.class) - .addStatement("beanDefinition.setAttribute(\"$L\", clazz)", FactoryBean.OBJECT_TYPE_ATTRIBUTE) - .addStatement("beanDefinition.setPrimary($L)", registeredBeanDefinition.isPrimary()) - .addStatement("$T holder = new $T(beanDefinition, \"$L\", new String[]$L)", BeanDefinitionHolder.class, - BeanDefinitionHolder.class, feignClientPropertyValues.get("type"), qualifiers) - .addStatement("$T.registerBeanDefinition(holder, registry) ", BeanDefinitionReaderUtils.class); + method.addJavadoc("register Feign Client: $L", feignClientPropertyValues.get("type")) + .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .addParameter(BeanDefinitionRegistry.class, "registry") + .addStatement("Class clazz = $T.resolveClassName(\"$L\", null)", ClassUtils.class, + feignClientPropertyValues.get("type")) + .addStatement("$T definition = $T.genericBeanDefinition($T.class)", BeanDefinitionBuilder.class, + BeanDefinitionBuilder.class, FeignClientFactoryBean.class) + .addStatement("definition.addPropertyValue(\"name\",\"$L\")", feignClientPropertyValues.get("name")) + .addStatement("definition.addPropertyValue(\"contextId\", \"$L\")", + feignClientPropertyValues.get("contextId")) + .addStatement("definition.addPropertyValue(\"type\", clazz)") + .addStatement("definition.addPropertyValue(\"url\", \"$L\")", feignClientPropertyValues.get("url")) + .addStatement("definition.addPropertyValue(\"path\", \"$L\")", + feignClientPropertyValues.get("path")) + .addStatement("definition.addPropertyValue(\"dismiss404\", $L)", + feignClientPropertyValues.get("dismiss404")) + .addStatement("definition.addPropertyValue(\"fallback\", $T.class)", + feignClientPropertyValues.get("fallback")) + .addStatement("definition.addPropertyValue(\"fallbackFactory\", $T.class)", + feignClientPropertyValues.get("fallbackFactory")) + .addStatement("definition.setAutowireMode($L)", registeredBeanDefinition.getAutowireMode()) + .addStatement("definition.setLazyInit($L)", + registeredBeanDefinition.getLazyInit() != null ? registeredBeanDefinition.getLazyInit() + : false) + .addStatement("$T beanDefinition = definition.getBeanDefinition()", AbstractBeanDefinition.class) + .addStatement("beanDefinition.setAttribute(\"$L\", clazz)", FactoryBean.OBJECT_TYPE_ATTRIBUTE) + .addStatement("beanDefinition.setPrimary($L)", registeredBeanDefinition.isPrimary()) + .addStatement("$T holder = new $T(beanDefinition, \"$L\", new String[]$L)", + BeanDefinitionHolder.class, BeanDefinitionHolder.class, + feignClientPropertyValues.get("type"), qualifiers) + .addStatement("$T.registerBeanDefinition(holder, registry) ", BeanDefinitionReaderUtils.class); } + } } 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 08e16e82..d4ed2f05 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 @@ -47,7 +47,7 @@ class FeignClientFactoryTest { } private FeignClientSpecification getSpec(String name, String className, Class configClass) { - return new FeignClientSpecification(name, className, new Class[] {configClass}); + return new FeignClientSpecification(name, className, new Class[] { configClass }); } @Test 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 ecc0937a..6f01b928 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,8 @@ public class FeignClientFactoryTests { parent.refresh(); FeignClientFactory context = new FeignClientFactory(); context.setApplicationContext(parent); - context.setConfigurations(Arrays.asList(getSpec("foo", null, FooConfig.class), getSpec("bar", null, 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 +78,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, String className, Class configClass) { - return new FeignClientSpecification(name, className, new Class[] {configClass}); + return new FeignClientSpecification(name, className, new Class[] { configClass }); } interface TestType { @@ -106,7 +107,7 @@ public class FeignClientFactoryTests { FeignClientFactory feignContext() { FeignClientFactory feignClientFactory = new FeignClientFactory(); feignClientFactory.setConfigurations(Collections.singletonList( - new FeignClientSpecification("test", null, 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/FeignAotTests.java b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/aot/FeignAotTests.java index 4c7a8107..de4061b2 100644 --- a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/aot/FeignAotTests.java +++ b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/aot/FeignAotTests.java @@ -1,3 +1,19 @@ +/* + * Copyright 2022-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.cloud.openfeign.aot; import java.net.URL; @@ -60,31 +76,31 @@ public class FeignAotTests { @SuppressWarnings("unchecked") void shouldStartFeignChildContextsFromAotContributions(CapturedOutput output) { WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( - AnnotationConfigServletWebApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class, - FeignAutoConfiguration.class)) - .withConfiguration(UserConfigurations.of(TestFeignConfiguration.class)) - .withPropertyValues("logging.level.org.springframework.cloud=DEBUG"); + AnnotationConfigServletWebApplicationContext::new) + .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class, + FeignAutoConfiguration.class)) + .withConfiguration(UserConfigurations.of(TestFeignConfiguration.class)) + .withPropertyValues("logging.level.org.springframework.cloud=DEBUG"); contextRunner.prepare(context -> { TestGenerationContext generationContext = new TestGenerationContext(TestTarget.class); ClassName className = new ApplicationContextAotGenerator().processAheadOfTime( - (GenericApplicationContext) context.getSourceApplicationContext(), generationContext); + (GenericApplicationContext) context.getSourceApplicationContext(), generationContext); generationContext.writeGeneratedContent(); TestCompiler compiler = TestCompiler.forSystem(); compiler.with(generationContext).compile(compiled -> { ServletWebServerApplicationContext freshApplicationContext = new ServletWebServerApplicationContext(); ApplicationContextInitializer initializer = compiled - .getInstance(ApplicationContextInitializer.class, className.toString()); + .getInstance(ApplicationContextInitializer.class, className.toString()); initializer.initialize(freshApplicationContext); assertThat(output).contains("Creating a FeignClientFactoryBean."); assertThat(output).contains("Refreshing FeignClientFactory-test-with-config", - "Refreshing FeignClientFactory-test"); + "Refreshing FeignClientFactory-test"); assertThat(output).doesNotContain("Instantiating bean from Test custom config", - "Instantiating bean from default custom config"); + "Instantiating bean from default custom config"); TestPropertyValues.of(AotDetector.AOT_ENABLED + "=true") - .applyToSystemProperties(freshApplicationContext::refresh); + .applyToSystemProperties(freshApplicationContext::refresh); assertThat(output).contains("Instantiating bean from Test custom config", - "Instantiating bean from default custom config"); + "Instantiating bean from default custom config"); assertThat(freshApplicationContext.getBean(TestFeignClient.class)).isNotNull(); assertThat(freshApplicationContext.getBean(TestFeignClientWithConfig.class)).isNotNull(); }); @@ -96,7 +112,8 @@ public class FeignAotTests { } @Configuration(proxyBeanMethods = false) - @EnableFeignClients(clients = {TestFeignClient.class, TestFeignClientWithConfig.class}, defaultConfiguration = DefaultConfiguration.class) + @EnableFeignClients(clients = { TestFeignClient.class, TestFeignClientWithConfig.class }, + defaultConfiguration = DefaultConfiguration.class) public static class TestFeignConfiguration { @Autowired