From 332d4a4c9c94f6b83dc9011b1b48e1e4318b1a2e Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 4 Aug 2022 09:35:11 +0200 Subject: [PATCH] Apply same order than original BPP This commit updates ImportAwareAotBeanPostProcessor to be priority ordered, with the same order as its original BeanPostProcessor. This makes sure that infrastructure beans can be post-processed if necessary See gh-28915 --- .../ImportAwareAotBeanPostProcessor.java | 9 ++- ...lassPostProcessorAotContributionTests.java | 61 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) 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 024cb9aac29c..e45124acc3b0 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.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 @@ * @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 Object postProcessBeforeInitialization(Object bean, String beanName) { 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 d90af2e0c863..d017f89ac557 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.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.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 @@ void applyToWhenHasImportAwareConfigurationRegistersBeanPostProcessorAfterApplic }); } + @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 @@ public void setImportMetadata(AnnotationMetadata importMetadata) { } + @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"); + } + + } + }