Skip to content

Commit f6875b1

Browse files
committed
Generate missing hints for custom PropertySource factories
Closes gh-30175
1 parent 230840a commit f6875b1

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

Diff for: spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java

+10
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.LinkedHashSet;
2828
import java.util.List;
2929
import java.util.Map;
30+
import java.util.Objects;
3031
import java.util.Set;
3132
import java.util.function.Predicate;
3233
import java.util.function.Supplier;
@@ -40,6 +41,7 @@
4041
import org.springframework.aot.generate.GeneratedMethod;
4142
import org.springframework.aot.generate.GenerationContext;
4243
import org.springframework.aot.hint.ExecutableMode;
44+
import org.springframework.aot.hint.MemberCategory;
4345
import org.springframework.aot.hint.ResourceHints;
4446
import org.springframework.aot.hint.RuntimeHints;
4547
import org.springframework.aot.hint.TypeReference;
@@ -650,13 +652,21 @@ private static class PropertySourcesAotContribution implements BeanFactoryInitia
650652

651653
@Override
652654
public void applyTo(GenerationContext generationContext, BeanFactoryInitializationCode beanFactoryInitializationCode) {
655+
registerRuntimeHints(generationContext.getRuntimeHints());
653656
GeneratedMethod generatedMethod = beanFactoryInitializationCode
654657
.getMethods()
655658
.add("processPropertySources", this::generateAddPropertySourceProcessorMethod);
656659
beanFactoryInitializationCode
657660
.addInitializer(generatedMethod.toMethodReference());
658661
}
659662

663+
private void registerRuntimeHints(RuntimeHints hints) {
664+
this.descriptors.stream().map(PropertySourceDescriptor::propertySourceFactory)
665+
.filter(Objects::nonNull).distinct()
666+
.forEach(factory -> hints.reflection()
667+
.registerType(factory, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
668+
}
669+
660670
private void generateAddPropertySourceProcessorMethod(MethodSpec.Builder method) {
661671
method.addJavadoc("Apply known @PropertySources to the environment.");
662672
method.addModifiers(Modifier.PRIVATE);

Diff for: spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorAotContributionTests.java

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,7 +29,9 @@
2929

3030
import org.springframework.aot.generate.MethodReference;
3131
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
32+
import org.springframework.aot.hint.MemberCategory;
3233
import org.springframework.aot.hint.ResourcePatternHint;
34+
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
3335
import org.springframework.aot.test.generate.TestGenerationContext;
3436
import org.springframework.beans.BeansException;
3537
import org.springframework.beans.factory.InitializingBean;
@@ -50,6 +52,7 @@
5052
import org.springframework.core.Ordered;
5153
import org.springframework.core.env.ConfigurableEnvironment;
5254
import org.springframework.core.io.ResourceLoader;
55+
import org.springframework.core.io.support.DefaultPropertySourceFactory;
5356
import org.springframework.core.test.tools.Compiled;
5457
import org.springframework.core.test.tools.TestCompiler;
5558
import org.springframework.core.type.AnnotationMetadata;
@@ -291,6 +294,16 @@ void applyToWhenHasPropertySourceWithDetailsRetainsThem() {
291294
});
292295
}
293296

297+
@Test
298+
void applyToWhenHasCustomFactoryRegistersHints() {
299+
BeanFactoryInitializationAotContribution contribution = getContribution(
300+
PropertySourceWithCustomFactoryConfiguration.class);
301+
contribution.applyTo(generationContext, beanFactoryInitializationCode);
302+
assertThat(RuntimeHintsPredicates.reflection().onType(CustomPropertySourcesFactory.class)
303+
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS))
304+
.accepts(generationContext.getRuntimeHints());
305+
}
306+
294307
@SuppressWarnings("unchecked")
295308
private void compile(BiConsumer<Consumer<GenericApplicationContext>, Compiled> result) {
296309
MethodReference methodReference = beanFactoryInitializationCode.getInitializers().get(0);
@@ -332,6 +345,13 @@ static class PropertySourceWithDetailsConfiguration {
332345

333346
}
334347

348+
@Configuration(proxyBeanMethods = false)
349+
@PropertySource(value = "classpath:org/springframework/context/annotation/p1.properties",
350+
factory = CustomPropertySourcesFactory.class)
351+
static class PropertySourceWithCustomFactoryConfiguration {
352+
353+
}
354+
335355
}
336356

337357
@Nested
@@ -379,4 +399,8 @@ private void assertPostProcessorEntry(BeanPostProcessor postProcessor, Class<?>
379399
.containsExactly(entry(key.getName(), value.getName()));
380400
}
381401

402+
static class CustomPropertySourcesFactory extends DefaultPropertySourceFactory {
403+
404+
}
405+
382406
}

0 commit comments

Comments
 (0)