Add missing AOT support for method overrides (including @Lookup)

Closes gh-34642
This commit is contained in:
Juergen Hoeller
2025-06-24 21:58:31 +02:00
parent cdf4c61d08
commit 4190209ead
7 changed files with 305 additions and 110 deletions
@@ -18,6 +18,7 @@ package org.springframework.context.aot;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.function.BiConsumer;
@@ -51,7 +52,9 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.MethodReplacer;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.ReplaceOverride;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.testfixture.beans.Employee;
import org.springframework.beans.testfixture.beans.Pet;
@@ -81,6 +84,7 @@ import org.springframework.context.testfixture.context.annotation.LazyConstructo
import org.springframework.context.testfixture.context.annotation.LazyFactoryMethodArgumentComponent;
import org.springframework.context.testfixture.context.annotation.LazyResourceFieldComponent;
import org.springframework.context.testfixture.context.annotation.LazyResourceMethodComponent;
import org.springframework.context.testfixture.context.annotation.LookupComponent;
import org.springframework.context.testfixture.context.annotation.PropertySourceConfiguration;
import org.springframework.context.testfixture.context.annotation.QualifierConfiguration;
import org.springframework.context.testfixture.context.annotation.ResourceComponent;
@@ -112,6 +116,7 @@ class ApplicationContextAotGeneratorTests {
void processAheadOfTimeWhenHasSimpleBean() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBeanDefinition("test", new RootBeanDefinition(SimpleComponent.class));
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("test");
@@ -119,6 +124,99 @@ class ApplicationContextAotGeneratorTests {
});
}
@Test
void processAheadOfTimeWhenHasNoAotContributions() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).isEmpty();
assertThat(compiled.getSourceFile())
.contains("beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver())")
.contains("beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE)");
});
}
@Test
void processAheadOfTimeWhenHasBeanFactoryInitializationAotProcessorExcludesProcessor() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBeanDefinition("test",
new RootBeanDefinition(NoOpBeanFactoryInitializationAotProcessor.class));
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).isEmpty();
});
}
@Test
void processAheadOfTimeWhenHasBeanRegistrationAotProcessorExcludesProcessor() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBeanDefinition("test",
new RootBeanDefinition(NoOpBeanRegistrationAotProcessor.class));
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).isEmpty();
});
}
@Test
void processAheadOfTimeWithPropertySource() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(PropertySourceConfiguration.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
ConfigurableEnvironment environment = freshApplicationContext.getEnvironment();
PropertySource<?> propertySource = environment.getPropertySources().get("testp1");
assertThat(propertySource).isNotNull();
assertThat(propertySource.getProperty("from.p1")).isEqualTo("p1Value");
});
}
@Test
void processAheadOfTimeWithQualifier() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(QualifierConfiguration.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
QualifierConfiguration configuration = freshApplicationContext.getBean(QualifierConfiguration.class);
assertThat(configuration).hasFieldOrPropertyWithValue("bean", "one");
});
}
@Test
void processAheadOfTimeWithInjectionPoint() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(InjectionPointConfiguration.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBean("classToString"))
.isEqualTo(InjectionPointConfiguration.class.getName());
});
}
@Test // gh-30689
void processAheadOfTimeWithExplicitResolvableType() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
DefaultListableBeanFactory beanFactory = applicationContext.getDefaultListableBeanFactory();
RootBeanDefinition beanDefinition = new RootBeanDefinition(One.class);
beanDefinition.setResolvedFactoryMethod(ReflectionUtils.findMethod(TestHierarchy.class, "oneBean"));
// Override target type
beanDefinition.setTargetType(Two.class);
beanFactory.registerBeanDefinition("hierarchyBean", beanDefinition);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBean(Two.class))
.isInstanceOf(Implementation.class);
});
}
@Nested
class Autowiring {
@@ -129,6 +227,7 @@ class ApplicationContextAotGeneratorTests {
AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME, AutowiredAnnotationBeanPostProcessor.class);
applicationContext.registerBeanDefinition("autowiredComponent", new RootBeanDefinition(AutowiredComponent.class));
registerIntegerBean(applicationContext, "number", 42);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("autowiredComponent", "number");
@@ -138,11 +237,56 @@ class ApplicationContextAotGeneratorTests {
});
}
@Test
void processAheadOfTimeWhenHasReplacer() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
registerBeanPostProcessor(applicationContext,
AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME, AutowiredAnnotationBeanPostProcessor.class);
RootBeanDefinition rbd = new RootBeanDefinition(AutowiredComponent.class);
rbd.getMethodOverrides().addOverride(
new ReplaceOverride("getCounter", "replacer"));
applicationContext.registerBeanDefinition("autowiredComponent", rbd);
registerIntegerBean(applicationContext, "number", 42);
applicationContext.registerBean("replacer", DummyReplacer.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("autowiredComponent", "number", "replacer");
AutowiredComponent bean = freshApplicationContext.getBean(AutowiredComponent.class);
assertThat(bean.getEnvironment()).isSameAs(freshApplicationContext.getEnvironment());
assertThat(bean.getCounter()).isEqualTo(44);
assertThat(bean.getCounter(0)).isEqualTo(42);
});
}
@Test
void processAheadOfTimeWhenHasLookup() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
registerBeanPostProcessor(applicationContext,
AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME, AutowiredAnnotationBeanPostProcessor.class);
RootBeanDefinition rbd = new RootBeanDefinition(LookupComponent.class);
rbd.getMethodOverrides().addOverride(
new ReplaceOverride("getCounter", "replacer", List.of( "Integer")));
applicationContext.registerBeanDefinition("autowiredComponent", rbd);
registerIntegerBean(applicationContext, "number", 42);
applicationContext.registerBean("replacer", DummyReplacer.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("autowiredComponent", "number", "replacer");
LookupComponent bean = freshApplicationContext.getBean(LookupComponent.class);
assertThat(bean.getEnvironment()).isSameAs(freshApplicationContext.getEnvironment());
assertThat(bean.getCounter()).isEqualTo(42);
assertThat(bean.getCounter(0)).isEqualTo(44);
});
}
@Test
void processAheadOfTimeWhenHasAutowiringOnUnresolvedGeneric() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(GenericTemplateConfiguration.class);
applicationContext.registerBean("autowiredComponent", AutowiredGenericTemplate.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
AutowiredGenericTemplate bean = freshApplicationContext.getBean(AutowiredGenericTemplate.class);
@@ -162,7 +306,6 @@ class ApplicationContextAotGeneratorTests {
assertThat(runtimeHints.proxies().jdkProxyHints()).anySatisfy(proxyHint ->
assertThat(proxyHint.getProxiedInterfaces()).isEqualTo(TypeReference.listOf(
environment.getClass().getInterfaces())));
});
}
@@ -226,15 +369,16 @@ class ApplicationContextAotGeneratorTests {
AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME, AutowiredAnnotationBeanPostProcessor.class);
applicationContext.registerBeanDefinition("testComponent", beanDefinition);
TestGenerationContext generationContext = processAheadOfTime(applicationContext);
testCompiledResult(generationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("testComponent");
assertions.accept(freshApplicationContext.getBean("testComponent", type), generationContext);
});
}
}
@Nested
class ResourceAutowiring {
@@ -247,6 +391,7 @@ class ApplicationContextAotGeneratorTests {
registerStringBean(applicationContext, "text2", "hello2");
registerIntegerBean(applicationContext, "number", 42);
applicationContext.registerBeanDefinition("resourceComponent", new RootBeanDefinition(ResourceComponent.class));
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("resourceComponent", "text", "text2", "number");
@@ -300,6 +445,7 @@ class ApplicationContextAotGeneratorTests {
AnnotationConfigUtils.COMMON_ANNOTATION_PROCESSOR_BEAN_NAME, CommonAnnotationBeanPostProcessor.class);
applicationContext.registerBeanDefinition("testComponent", beanDefinition);
TestGenerationContext generationContext = processAheadOfTime(applicationContext);
testCompiledResult(generationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("testComponent");
@@ -308,6 +454,7 @@ class ApplicationContextAotGeneratorTests {
}
}
@Nested
class InitDestroy {
@@ -318,6 +465,7 @@ class ApplicationContextAotGeneratorTests {
AnnotationConfigUtils.COMMON_ANNOTATION_PROCESSOR_BEAN_NAME, CommonAnnotationBeanPostProcessor.class);
applicationContext.registerBeanDefinition("initDestroyComponent",
new RootBeanDefinition(InitDestroyComponent.class));
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("initDestroyComponent");
@@ -337,6 +485,7 @@ class ApplicationContextAotGeneratorTests {
beanDefinition.setInitMethodName("customInit");
beanDefinition.setDestroyMethodName("customDestroy");
applicationContext.registerBeanDefinition("initDestroyComponent", beanDefinition);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).containsOnly("initDestroyComponent");
@@ -346,94 +495,8 @@ class ApplicationContextAotGeneratorTests {
assertThat(bean.events).containsExactly("init", "customInit", "destroy", "customDestroy");
});
}
}
@Test
void processAheadOfTimeWhenHasNoAotContributions() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).isEmpty();
assertThat(compiled.getSourceFile())
.contains("beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver())")
.contains("beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE)");
});
}
@Test
void processAheadOfTimeWhenHasBeanFactoryInitializationAotProcessorExcludesProcessor() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBeanDefinition("test",
new RootBeanDefinition(NoOpBeanFactoryInitializationAotProcessor.class));
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).isEmpty();
});
}
@Test
void processAheadOfTimeWhenHasBeanRegistrationAotProcessorExcludesProcessor() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBeanDefinition("test",
new RootBeanDefinition(NoOpBeanRegistrationAotProcessor.class));
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBeanDefinitionNames()).isEmpty();
});
}
@Test
void processAheadOfTimeWithPropertySource() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(PropertySourceConfiguration.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
ConfigurableEnvironment environment = freshApplicationContext.getEnvironment();
PropertySource<?> propertySource = environment.getPropertySources().get("testp1");
assertThat(propertySource).isNotNull();
assertThat(propertySource.getProperty("from.p1")).isEqualTo("p1Value");
});
}
@Test
void processAheadOfTimeWithQualifier() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(QualifierConfiguration.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
QualifierConfiguration configuration = freshApplicationContext.getBean(QualifierConfiguration.class);
assertThat(configuration).hasFieldOrPropertyWithValue("bean", "one");
});
}
@Test
void processAheadOfTimeWithInjectionPoint() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(InjectionPointConfiguration.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBean("classToString"))
.isEqualTo(InjectionPointConfiguration.class.getName());
});
}
@Test // gh-30689
void processAheadOfTimeWithExplicitResolvableType() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
DefaultListableBeanFactory beanFactory = applicationContext.getDefaultListableBeanFactory();
RootBeanDefinition beanDefinition = new RootBeanDefinition(One.class);
beanDefinition.setResolvedFactoryMethod(ReflectionUtils.findMethod(TestHierarchy.class, "oneBean"));
// Override target type
beanDefinition.setTargetType(Two.class);
beanFactory.registerBeanDefinition("hierarchyBean", beanDefinition);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBean(Two.class))
.isInstanceOf(Implementation.class);
});
}
@Nested
@CompileWithForkedClassLoader
@@ -499,6 +562,7 @@ class ApplicationContextAotGeneratorTests {
void processAheadOfTimeWhenHasCglibProxyUseProxy() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(CglibConfiguration.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBean("prefix", String.class)).isEqualTo("Hello0");
@@ -510,6 +574,7 @@ class ApplicationContextAotGeneratorTests {
void processAheadOfTimeWhenHasCglibProxyAndAutowiring() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(AutowiredCglibConfiguration.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(context -> {
context.setEnvironment(new MockEnvironment().withProperty("hello", "Hi"));
@@ -523,6 +588,7 @@ class ApplicationContextAotGeneratorTests {
void processAheadOfTimeWhenHasCglibProxyAndMixedAutowiring() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(AutowiredMixedCglibConfiguration.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(context -> {
context.setEnvironment(new MockEnvironment().withProperty("hello", "Hi")
@@ -537,6 +603,7 @@ class ApplicationContextAotGeneratorTests {
void processAheadOfTimeWhenHasCglibProxyWithAnnotationsOnTheUserClasConstructor() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean("config", ValueCglibConfiguration.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(context -> {
context.setEnvironment(new MockEnvironment().withProperty("name", "AOT World"));
@@ -551,6 +618,7 @@ class ApplicationContextAotGeneratorTests {
void processAheadOfTimeWhenHasCglibProxyWithArgumentsUseProxy() {
GenericApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.registerBean(ConfigurableCglibConfiguration.class);
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = createFreshApplicationContext(initializer);
freshApplicationContext.setEnvironment(new MockEnvironment().withProperty("test.prefix", "Hi"));
@@ -573,9 +641,9 @@ class ApplicationContextAotGeneratorTests {
private String toCglibClassSimpleName(Class<?> configClass) {
return configClass.getSimpleName() + CGLIB_CONFIGURATION_CLASS_SUFFIX;
}
}
@Nested
class ActiveProfile {
@@ -586,6 +654,7 @@ class ApplicationContextAotGeneratorTests {
if (aotProfiles.length != 0) {
applicationContext.getEnvironment().setActiveProfiles(aotProfiles);
}
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = new GenericApplicationContext();
if (runtimeProfiles.length != 0) {
@@ -604,17 +673,18 @@ class ApplicationContextAotGeneratorTests {
Arguments.of(new String[] { "aot", "prod" }, new String[] { "aot", "prod" }, new String[] { "aot", "prod" }),
Arguments.of(new String[] { "default" }, new String[] {}, new String[] {}));
}
}
@Nested
class XmlSupport {
@Test
void processAheadOfTimeWhenHasTypedStringValue() {
GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext();
applicationContext
.load(new ClassPathResource("applicationContextAotGeneratorTests-values.xml", getClass()));
applicationContext.load(
new ClassPathResource("applicationContextAotGeneratorTests-values.xml", getClass()));
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
Employee employee = freshApplicationContext.getBean(Employee.class);
@@ -631,8 +701,9 @@ class ApplicationContextAotGeneratorTests {
@Test
void processAheadOfTimeWhenHasTypedStringValueWithType() {
GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext();
applicationContext
.load(new ClassPathResource("applicationContextAotGeneratorTests-values-types.xml", getClass()));
applicationContext.load(
new ClassPathResource("applicationContextAotGeneratorTests-values-types.xml", getClass()));
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
Employee employee = freshApplicationContext.getBean(Employee.class);
@@ -647,8 +718,9 @@ class ApplicationContextAotGeneratorTests {
@Test
void processAheadOfTimeWhenHasTypedStringValueWithExpression() {
GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext();
applicationContext
.load(new ClassPathResource("applicationContextAotGeneratorTests-values-expressions.xml", getClass()));
applicationContext.load(
new ClassPathResource("applicationContextAotGeneratorTests-values-expressions.xml", getClass()));
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
Employee employee = freshApplicationContext.getBean(Employee.class);
@@ -663,8 +735,9 @@ class ApplicationContextAotGeneratorTests {
@Test
void processAheadOfTimeWhenXmlHasBeanReferences() {
GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext();
applicationContext
.load(new ClassPathResource("applicationContextAotGeneratorTests-references.xml", getClass()));
applicationContext.load(
new ClassPathResource("applicationContextAotGeneratorTests-references.xml", getClass()));
testCompiledResult(applicationContext, (initializer, compiled) -> {
GenericApplicationContext freshApplicationContext = toFreshApplicationContext(initializer);
assertThat(freshApplicationContext.getBean("petInnerBean", Pet.class)
@@ -673,11 +746,11 @@ class ApplicationContextAotGeneratorTests {
.getName()).isEqualTo("Dofi");
});
}
}
@Nested
class ExceptionHanding {
class ExceptionHandling {
@Test
void failureProcessingBeanFactoryAotContribution() {
@@ -692,6 +765,7 @@ class ApplicationContextAotGeneratorTests {
}
}
private static void registerBeanPostProcessor(GenericApplicationContext applicationContext,
String beanName, Class<?> beanPostProcessorClass) {
@@ -716,7 +790,7 @@ class ApplicationContextAotGeneratorTests {
.getBeanDefinition());
}
private Consumer<List<? extends JdkProxyHint>> doesNotHaveProxyFor(Class<?> target) {
private static Consumer<List<? extends JdkProxyHint>> doesNotHaveProxyFor(Class<?> target) {
return hints -> assertThat(hints).noneMatch(hint ->
hint.getProxiedInterfaces().get(0).equals(TypeReference.of(target)));
}
@@ -771,7 +845,6 @@ class ApplicationContextAotGeneratorTests {
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
return null;
}
}
@@ -782,9 +855,9 @@ class ApplicationContextAotGeneratorTests {
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
return null;
}
}
static class FailingBeanFactoryInitializationAotContribution implements BeanFactoryInitializationAotProcessor {
@Override
@@ -793,4 +866,13 @@ class ApplicationContextAotGeneratorTests {
}
}
public static class DummyReplacer implements MethodReplacer {
@Override
public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
return 44;
}
}
}