Skip to content

Commit e749cd1

Browse files
committed
Add constructor introspection hint on Configuration class target
See gh-29358
1 parent 7e0a039 commit e749cd1

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
import org.springframework.aop.framework.autoproxy.AutoProxyUtils;
4040
import org.springframework.aot.generate.GeneratedMethod;
4141
import org.springframework.aot.generate.GenerationContext;
42+
import org.springframework.aot.hint.ExecutableMode;
4243
import org.springframework.aot.hint.ResourceHints;
44+
import org.springframework.aot.hint.RuntimeHints;
4345
import org.springframework.aot.hint.TypeReference;
4446
import org.springframework.beans.PropertyValues;
4547
import org.springframework.beans.factory.BeanClassLoaderAware;
@@ -739,20 +741,22 @@ public CodeBlock generateSetBeanDefinitionPropertiesCode(GenerationContext gener
739741
public CodeBlock generateInstanceSupplierCode(GenerationContext generationContext,
740742
BeanRegistrationCode beanRegistrationCode, Executable constructorOrFactoryMethod,
741743
boolean allowDirectSupplierShortcut) {
744+
Executable executableToUse = proxyExecutable(generationContext.getRuntimeHints(), constructorOrFactoryMethod);
742745
return super.generateInstanceSupplierCode(generationContext, beanRegistrationCode,
743-
proxyExecutable(constructorOrFactoryMethod), allowDirectSupplierShortcut);
746+
executableToUse, allowDirectSupplierShortcut);
744747
}
745748

746-
private Executable proxyExecutable(Executable rawClassExecutable) {
747-
if (rawClassExecutable instanceof Constructor<?>) {
749+
private Executable proxyExecutable(RuntimeHints runtimeHints, Executable userExecutable) {
750+
if (userExecutable instanceof Constructor<?> userConstructor) {
748751
try {
749-
return this.proxyClass.getConstructor(rawClassExecutable.getParameterTypes());
752+
runtimeHints.reflection().registerConstructor(userConstructor, ExecutableMode.INTROSPECT);
753+
return this.proxyClass.getConstructor(userExecutable.getParameterTypes());
750754
}
751755
catch (NoSuchMethodException ex) {
752756
throw new IllegalStateException("No matching constructor found on proxy " + this.proxyClass, ex);
753757
}
754758
}
755-
return rawClassExecutable;
759+
return userExecutable;
756760
}
757761

758762
}

spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.context.aot;
1818

1919
import java.io.IOException;
20+
import java.lang.reflect.Constructor;
2021
import java.lang.reflect.Proxy;
2122
import java.util.List;
2223
import java.util.function.BiConsumer;
@@ -333,6 +334,16 @@ void processAheadOfTimeWhenHasCglibProxyWithArgumentsUseProxy() {
333334
});
334335
}
335336

337+
@Test
338+
void processAheadOfTimeWhenHasCglibProxyWithArgumentsRegisterIntrospectionHintsOnUserClass() {
339+
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
340+
applicationContext.registerBean(ConfigurableCglibConfiguration.class);
341+
TestGenerationContext generationContext = processAheadOfTime(applicationContext);
342+
Constructor<?> userConstructor = ConfigurableCglibConfiguration.class.getDeclaredConstructors()[0];
343+
assertThat(RuntimeHintsPredicates.reflection().onConstructor(userConstructor).introspect())
344+
.accepts(generationContext.getRuntimeHints());
345+
}
346+
336347
}
337348

338349
private Consumer<List<? extends JdkProxyHint>> doesNotHaveProxyFor(Class<?> target) {

0 commit comments

Comments
 (0)