Add constructor introspection hint on Configuration class target

See gh-29358
This commit is contained in:
Stephane Nicoll 2022-10-20 12:10:21 +02:00
parent 7e0a039291
commit e749cd1ef1
2 changed files with 20 additions and 5 deletions

View File

@ -39,7 +39,9 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.autoproxy.AutoProxyUtils;
import org.springframework.aot.generate.GeneratedMethod;
import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.ResourceHints;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.TypeReference;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanClassLoaderAware;
@ -739,20 +741,22 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
public CodeBlock generateInstanceSupplierCode(GenerationContext generationContext,
BeanRegistrationCode beanRegistrationCode, Executable constructorOrFactoryMethod,
boolean allowDirectSupplierShortcut) {
Executable executableToUse = proxyExecutable(generationContext.getRuntimeHints(), constructorOrFactoryMethod);
return super.generateInstanceSupplierCode(generationContext, beanRegistrationCode,
proxyExecutable(constructorOrFactoryMethod), allowDirectSupplierShortcut);
executableToUse, allowDirectSupplierShortcut);
}
private Executable proxyExecutable(Executable rawClassExecutable) {
if (rawClassExecutable instanceof Constructor<?>) {
private Executable proxyExecutable(RuntimeHints runtimeHints, Executable userExecutable) {
if (userExecutable instanceof Constructor<?> userConstructor) {
try {
return this.proxyClass.getConstructor(rawClassExecutable.getParameterTypes());
runtimeHints.reflection().registerConstructor(userConstructor, ExecutableMode.INTROSPECT);
return this.proxyClass.getConstructor(userExecutable.getParameterTypes());
}
catch (NoSuchMethodException ex) {
throw new IllegalStateException("No matching constructor found on proxy " + this.proxyClass, ex);
}
}
return rawClassExecutable;
return userExecutable;
}
}

View File

@ -17,6 +17,7 @@
package org.springframework.context.aot;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.function.BiConsumer;
@ -333,6 +334,16 @@ class ApplicationContextAotGeneratorTests {
});
}
@Test
void processAheadOfTimeWhenHasCglibProxyWithArgumentsRegisterIntrospectionHintsOnUserClass() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(ConfigurableCglibConfiguration.class);
TestGenerationContext generationContext = processAheadOfTime(applicationContext);
Constructor<?> userConstructor = ConfigurableCglibConfiguration.class.getDeclaredConstructors()[0];
assertThat(RuntimeHintsPredicates.reflection().onConstructor(userConstructor).introspect())
.accepts(generationContext.getRuntimeHints());
}
}
private Consumer<List<? extends JdkProxyHint>> doesNotHaveProxyFor(Class<?> target) {