Browse Source

Add constructor introspection hint on Configuration class target

See gh-29358
pull/29364/head
Stephane Nicoll 3 years ago
parent
commit
e749cd1ef1
  1. 14
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java
  2. 11
      spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java

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

@ -39,7 +39,9 @@ import org.apache.commons.logging.LogFactory; @@ -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 @@ -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;
}
}

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

@ -17,6 +17,7 @@ @@ -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 { @@ -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) {

Loading…
Cancel
Save