Fix adding hints for EnvironmentRepositoryFactory classes.
This commit is contained in:
@@ -20,12 +20,10 @@ import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
@@ -49,6 +47,7 @@ import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.cloud.config.server.composite.CompositeEnvironmentBeanFactoryPostProcessor;
|
||||
import org.springframework.cloud.config.server.composite.CompositeUtils;
|
||||
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
|
||||
import org.springframework.cloud.config.server.environment.EnvironmentRepositoryFactory;
|
||||
import org.springframework.cloud.config.server.support.EnvironmentRepositoryProperties;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.javapoet.MethodSpec;
|
||||
@@ -70,8 +69,8 @@ public class CompositeEnvironmentBeanFactoryInitializationAotProcessor
|
||||
"-env-repo-properties", EnvironmentRepositoryProperties.class);
|
||||
Map<String, BeanDefinition> repoBeanDefinitions = getCompositeEnvironmentBeanDefinitions(beanFactory,
|
||||
"-env-repo", EnvironmentRepository.class);
|
||||
return new org.springframework.cloud.config.server.aot.CompositeEnvironmentBeanFactoryInitializationAotProcessor.CompositeEnvironmentBeanFactoryInitializationAotContribution(
|
||||
propertyBeanDefinitions, repoBeanDefinitions, beanFactory);
|
||||
return new CompositeEnvironmentBeanFactoryInitializationAotContribution(propertyBeanDefinitions,
|
||||
repoBeanDefinitions, beanFactory);
|
||||
}
|
||||
|
||||
private static Map<String, BeanDefinition> getCompositeEnvironmentBeanDefinitions(
|
||||
@@ -106,7 +105,7 @@ public class CompositeEnvironmentBeanFactoryInitializationAotProcessor
|
||||
|
||||
private final ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
private final Set<Class<? extends EnvironmentRepositoryProperties>> propertiesClasses = new HashSet<>();
|
||||
private final Set<Class<?>> hintClasses = new HashSet<>();
|
||||
|
||||
private CompositeEnvironmentBeanFactoryInitializationAotContribution(
|
||||
Map<String, BeanDefinition> propertyBeanDefinitions, Map<String, BeanDefinition> repoBeanDefinitions,
|
||||
@@ -121,7 +120,7 @@ public class CompositeEnvironmentBeanFactoryInitializationAotProcessor
|
||||
BeanFactoryInitializationCode beanFactoryInitializationCode) {
|
||||
GeneratedMethod environmentRepositoryPropertiesGeneratedMethod = beanFactoryInitializationCode.getMethods()
|
||||
.add("registerCompositeEnvironmentRepositoryPropertiesBeanDefinitions",
|
||||
this::generateRegisterPropertyBeanDefinitionsMethod);
|
||||
this::generateRegisterBeanDefinitionsMethod);
|
||||
beanFactoryInitializationCode
|
||||
.addInitializer(environmentRepositoryPropertiesGeneratedMethod.toMethodReference());
|
||||
generateRuntimeHints(generationContext.getRuntimeHints());
|
||||
@@ -129,28 +128,15 @@ public class CompositeEnvironmentBeanFactoryInitializationAotProcessor
|
||||
|
||||
private void generateRuntimeHints(RuntimeHints runtimeHints) {
|
||||
ReflectionHints hints = runtimeHints.reflection();
|
||||
Stream.concat(propertyBeanDefinitions.values().stream(), repoBeanDefinitions.values().stream())
|
||||
.map(BeanDefinition::getBeanClassName).filter(Objects::nonNull).map(beanClassName -> {
|
||||
try {
|
||||
return Class.forName(beanClassName);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException("Class " + beanClassName + " could not be found", e);
|
||||
}
|
||||
}).forEach(beanClassName -> {
|
||||
hints.registerType(TypeReference.of(beanClassName), MemberCategory.INTROSPECT_PUBLIC_METHODS,
|
||||
MemberCategory.INTROSPECT_DECLARED_METHODS);
|
||||
introspectPublicMethodsOnAllInterfaces(hints, beanClassName);
|
||||
});
|
||||
for (Class<? extends EnvironmentRepositoryProperties> propertiesClass : propertiesClasses) {
|
||||
hints.registerType(TypeReference.of(propertiesClass), MemberCategory.INTROSPECT_PUBLIC_METHODS,
|
||||
for (Class<?> clazz : hintClasses) {
|
||||
hints.registerType(TypeReference.of(clazz), MemberCategory.INVOKE_PUBLIC_METHODS,
|
||||
MemberCategory.INTROSPECT_DECLARED_METHODS);
|
||||
introspectPublicMethodsOnAllInterfaces(hints, propertiesClass);
|
||||
introspectPublicMethodsOnAllInterfaces(hints, clazz);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void generateRegisterPropertyBeanDefinitionsMethod(MethodSpec.Builder method) {
|
||||
private void generateRegisterBeanDefinitionsMethod(MethodSpec.Builder method) {
|
||||
method.addJavadoc(
|
||||
"Register the EnvironmentRepositoryProperties bean definitions for composite config data sources.");
|
||||
method.addModifiers(Modifier.PUBLIC);
|
||||
@@ -160,13 +146,16 @@ public class CompositeEnvironmentBeanFactoryInitializationAotProcessor
|
||||
Pattern findIndexPattern = Pattern.compile("(^.*)(-env-repo-properties)([0-9]+)$");
|
||||
propertyBeanDefinitions.keySet().forEach(beanName -> {
|
||||
Matcher matcher = findIndexPattern.matcher(beanName);
|
||||
String repoBeanName = beanName.replace("repo-properties", "repo");
|
||||
String factoryName = repoBeanDefinitions.get(repoBeanName).getFactoryBeanName();
|
||||
Type propertyType = CompositeUtils.getEnvironmentRepositoryFactoryTypeParams(beanFactory,
|
||||
factoryName)[1];
|
||||
Class<? extends EnvironmentRepositoryProperties> propertiesClass = (Class<? extends EnvironmentRepositoryProperties>) propertyType;
|
||||
propertiesClasses.add(propertiesClass);
|
||||
if (matcher.find()) {
|
||||
String repoBeanName = beanName.replace("repo-properties", "repo");
|
||||
String factoryName = repoBeanDefinitions.get(repoBeanName).getFactoryBeanName();
|
||||
Class<? extends EnvironmentRepositoryFactory<? extends EnvironmentRepository, ? extends EnvironmentRepositoryProperties>> factoryClass = (Class<? extends EnvironmentRepositoryFactory<? extends EnvironmentRepository, ? extends EnvironmentRepositoryProperties>>) CompositeUtils
|
||||
.getFactoryClass(beanFactory, factoryName);
|
||||
Type[] environmentRepositoryFactoryTypeParams = CompositeUtils
|
||||
.getEnvironmentRepositoryFactoryTypeParams(factoryClass);
|
||||
Class<? extends EnvironmentRepositoryProperties> repoClass = (Class<? extends EnvironmentRepositoryProperties>) environmentRepositoryFactoryTypeParams[0];
|
||||
Class<? extends EnvironmentRepositoryProperties> propertiesClass = (Class<? extends EnvironmentRepositoryProperties>) environmentRepositoryFactoryTypeParams[1];
|
||||
hintClasses.addAll(Set.of(repoClass, propertiesClass, factoryClass));
|
||||
String indexString = matcher.group(3);
|
||||
int index = Integer.parseInt(indexString);
|
||||
String environmentConfigurationPropertyName = String
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018-2019 the original author or authors.
|
||||
* Copyright 2018-2024 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.
|
||||
@@ -31,10 +31,12 @@ import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.cloud.config.server.environment.EnvironmentRepositoryFactory;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.type.MethodMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Dylan Roberts
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
public final class CompositeUtils {
|
||||
|
||||
@@ -68,7 +70,7 @@ public final class CompositeUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a Factory Name return the generic type parameters of the factory (The actual
|
||||
* Given a Factory Name, return the generic type parameters of the factory (The actual
|
||||
* repository class, and its properties class).
|
||||
* @param beanFactory Spring Bean Factory
|
||||
* @param factoryName name of the factory
|
||||
@@ -76,14 +78,17 @@ public final class CompositeUtils {
|
||||
*/
|
||||
public static Type[] getEnvironmentRepositoryFactoryTypeParams(ConfigurableListableBeanFactory beanFactory,
|
||||
String factoryName) {
|
||||
MethodMetadata methodMetadata = (MethodMetadata) beanFactory.getBeanDefinition(factoryName).getSource();
|
||||
Class<?> factoryClass = null;
|
||||
try {
|
||||
factoryClass = Class.forName(methodMetadata.getReturnTypeName());
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
Class<?> factoryClass = getFactoryClass(beanFactory, factoryName);
|
||||
return getEnvironmentRepositoryFactoryTypeParams(factoryClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a Factory {@link Class}, return the generic type parameters of the factory
|
||||
* (The actual repository class, and its properties class).
|
||||
* @param factoryClass Factory {@link Class}
|
||||
* @return generic type params of the factory
|
||||
*/
|
||||
public static Type[] getEnvironmentRepositoryFactoryTypeParams(Class<?> factoryClass) {
|
||||
Optional<AnnotatedType> annotatedFactoryType = Arrays.stream(factoryClass.getAnnotatedInterfaces())
|
||||
.filter(i -> {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) i.getType();
|
||||
@@ -94,6 +99,25 @@ public final class CompositeUtils {
|
||||
return factoryParameterizedType.getActualTypeArguments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a Factory Name, return the Factory {@link Class}.
|
||||
* @param beanFactory Spring Bean Factory
|
||||
* @param factoryName name of the factory
|
||||
* @return factory {@link Class}
|
||||
*/
|
||||
public static Class<?> getFactoryClass(ConfigurableListableBeanFactory beanFactory, String factoryName) {
|
||||
MethodMetadata methodMetadata = (MethodMetadata) beanFactory.getBeanDefinition(factoryName).getSource();
|
||||
Assert.notNull(methodMetadata, "Factory MethodMetadata cannot be null.");
|
||||
Class<?> factoryClass;
|
||||
try {
|
||||
factoryClass = Class.forName(methodMetadata.getReturnTypeName());
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return factoryClass;
|
||||
}
|
||||
|
||||
static class CompositeConfig {
|
||||
|
||||
List<Map<String, Object>> composite;
|
||||
|
||||
Reference in New Issue
Block a user