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
This commit is contained in:
Stephane Nicoll 2022-08-04 09:35:11 +02:00
parent e5f9574800
commit 332d4a4c9c
2 changed files with 69 additions and 1 deletions

View File

@ -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) {

View File

@ -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");
}
}
}