diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ImportAwareAotBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/ImportAwareAotBeanPostProcessor.java index 024cb9aac2..e45124acc3 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ImportAwareAotBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ImportAwareAotBeanPostProcessor.java @@ -20,6 +20,8 @@ import java.io.IOException; import java.util.Map; import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.core.Ordered; +import org.springframework.core.PriorityOrdered; import org.springframework.core.type.classreading.CachingMetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; @@ -33,7 +35,7 @@ import org.springframework.util.ClassUtils; * @author Stephane Nicoll * @since 6.0 */ -public final class ImportAwareAotBeanPostProcessor implements BeanPostProcessor { +public final class ImportAwareAotBeanPostProcessor implements BeanPostProcessor, PriorityOrdered { private final MetadataReaderFactory metadataReaderFactory; @@ -54,6 +56,11 @@ public final class ImportAwareAotBeanPostProcessor implements BeanPostProcessor return bean; } + @Override + public int getOrder() { + return Ordered.LOWEST_PRECEDENCE; // match priority of original post processor + } + private void setAnnotationMetadata(ImportAware instance) { String importingClass = getImportingClassFor(instance); if (importingClass == null) { diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorAotContributionTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorAotContributionTests.java index d90af2e0c8..d017f89ac5 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorAotContributionTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorAotContributionTests.java @@ -31,6 +31,7 @@ import org.springframework.aot.hint.ResourcePatternHint; import org.springframework.aot.test.generator.compile.Compiled; import org.springframework.aot.test.generator.compile.TestCompiler; import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.support.DefaultListableBeanFactory; @@ -42,12 +43,14 @@ import org.springframework.context.ApplicationContextAware; import org.springframework.context.support.GenericApplicationContext; import org.springframework.context.testfixture.context.generator.annotation.ImportAwareConfiguration; import org.springframework.context.testfixture.context.generator.annotation.ImportConfiguration; +import org.springframework.core.Ordered; import org.springframework.core.testfixture.aot.generate.TestGenerationContext; import org.springframework.core.type.AnnotationMetadata; import org.springframework.javapoet.CodeBlock; import org.springframework.javapoet.MethodSpec; import org.springframework.javapoet.ParameterizedTypeName; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; @@ -110,6 +113,27 @@ class ConfigurationClassPostProcessorAotContributionTests { }); } + @Test + void applyToWhenHasImportAwareConfigurationRegistersBeanPostProcessorBeforeRegularBeanPostProcessor() { + BeanFactoryInitializationAotContribution contribution = getContribution( + TestImportAwareBeanPostProcessorConfiguration.class); + contribution.applyTo(this.generationContext, this.beanFactoryInitializationCode); + compile((initializer, compiled) -> { + GenericApplicationContext freshContext = new GenericApplicationContext(); + DefaultListableBeanFactory freshBeanFactory = freshContext.getDefaultListableBeanFactory(); + initializer.accept(freshBeanFactory); + freshBeanFactory.registerBeanDefinition(TestImportAwareBeanPostProcessor.class.getName(), + new RootBeanDefinition(TestImportAwareBeanPostProcessor.class)); + RootBeanDefinition bd = new RootBeanDefinition(String.class); + bd.setInstanceSupplier(() -> "test"); + freshBeanFactory.registerBeanDefinition("testProcessing", bd); + freshContext.refresh(); + assertThat(freshContext.getBean("testProcessing")).isInstanceOfSatisfying(AnnotationMetadata.class, metadata -> + assertThat(metadata.getClassName()).isEqualTo(TestImportAwareBeanPostProcessorConfiguration.class.getName()) + ); + }); + } + @Test void applyToWhenHasImportAwareConfigurationRegistersHints() { BeanFactoryInitializationAotContribution contribution = getContribution( @@ -178,4 +202,41 @@ class ConfigurationClassPostProcessorAotContributionTests { } + @Configuration(proxyBeanMethods = false) + @Import(TestImportAwareBeanPostProcessor.class) + static class TestImportAwareBeanPostProcessorConfiguration { + + } + + static class TestImportAwareBeanPostProcessor implements BeanPostProcessor, ImportAware, + Ordered, InitializingBean { + + private AnnotationMetadata metadata; + + @Override + public void setImportMetadata(AnnotationMetadata importMetadata) { + this.metadata = importMetadata; + } + + @Nullable + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + if (beanName.equals("testProcessing")) { + return this.metadata; + } + return bean; + } + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } + + @Override + public void afterPropertiesSet() throws Exception { + Assert.notNull(this.metadata, "Metadata was not injected"); + } + + } + }