Use ManagedType BeanDefinition for AOT processing when possible.

We now try to read the types directly from the bean definition arguments first, before attempting to resolve the actual bean instance.
If resolving the bean fails, we currently only log an info message. This arrangement needs to be revisited.

See: #2593
This commit is contained in:
Christoph Strobl
2022-07-13 10:57:18 +02:00
parent cfac78867e
commit 74e52612bf
2 changed files with 83 additions and 4 deletions

View File

@@ -16,6 +16,8 @@
package org.springframework.data.aot;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import java.util.Collections;
import java.util.function.Consumer;
@@ -28,6 +30,7 @@ import org.springframework.aot.generate.GeneratedClasses;
import org.springframework.aot.generate.InMemoryGeneratedFiles;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
@@ -51,7 +54,7 @@ class ManagedTypesBeanRegistrationAotProcessorUnitTests {
@BeforeEach
void beforeEach() {
beanFactory = new DefaultListableBeanFactory();
beanFactory = spy(new DefaultListableBeanFactory());
}
@Test // GH-2593
@@ -65,6 +68,16 @@ class ManagedTypesBeanRegistrationAotProcessorUnitTests {
assertThat(contribution).isNotNull();
}
@Test // GH-2593
void processesBeanDefinitionIfPossibleWithoutLoadingTheBean() {
beanFactory.registerBeanDefinition("commons.managed-types", managedTypesDefinition);
createPostProcessor("commons").processAheadOfTime(RegisteredBean.of(beanFactory, "commons.managed-types"));
verify(beanFactory, never()).getBean(eq("commons.managed-types"), eq(ManagedTypes.class));
}
@Test // GH-2593
void contributesReflectionForManagedTypes() {
@@ -94,6 +107,16 @@ class ManagedTypesBeanRegistrationAotProcessorUnitTests {
assertThat(contribution).isNotNull();
}
@Test // GH-2593
void processesMatchingSubtypeBeanByAttemptingToLoadItIfNoMatchingConstructorArgumentFound() {
beanFactory.registerBeanDefinition("commons.managed-types", myManagedTypesDefinition);
createPostProcessor("commons").processAheadOfTime(RegisteredBean.of(beanFactory, "commons.managed-types"));
verify(beanFactory).getBean(eq("commons.managed-types"), eq(ManagedTypes.class));
}
@Test // GH-2593
void ignoresBeanNotMatchingRequiredType() {
@@ -117,6 +140,26 @@ class ManagedTypesBeanRegistrationAotProcessorUnitTests {
assertThat(contribution).isNull();
}
@Test // GH-2593
void returnsEmptyContributionWhenBeanCannotBeLoaded() {
doThrow(new BeanCreationException("o_O")).when(beanFactory).getBean(eq("commons.managed-types"),
eq(ManagedTypes.class));
beanFactory.registerBeanDefinition("commons.managed-types", myManagedTypesDefinition);
BeanRegistrationAotContribution contribution = createPostProcessor("commons")
.processAheadOfTime(RegisteredBean.of(beanFactory, "commons.managed-types"));
DefaultGenerationContext generationContext = new DefaultGenerationContext(
new GeneratedClasses(new ClassNameGenerator(Object.class)), new InMemoryGeneratedFiles(), new RuntimeHints());
contribution.applyTo(generationContext, null);
assertThat(generationContext.getRuntimeHints().reflection().typeHints()).isEmpty();
verify(beanFactory).getBean(eq("commons.managed-types"), eq(ManagedTypes.class));
}
private ManagedTypesBeanRegistrationAotProcessor createPostProcessor(String moduleIdentifier) {
ManagedTypesBeanRegistrationAotProcessor postProcessor = new ManagedTypesBeanRegistrationAotProcessor();
postProcessor.setModuleIdentifier(moduleIdentifier);