Allow MergedBeanDefinitionPostProcessor to handle bean creation
This commit registers the MergedBeanDefinitionPostProcessor instances on the BeanFactory processed for AOT purposes. This allows beans that are created at build-time to be post-processed for low-level needs such as initialization and autowiring. Closes gh-28777
This commit is contained in:
@@ -431,6 +431,24 @@ class AnnotationConfigApplicationContextTests {
|
||||
"annotationConfigApplicationContextTests.Config", "testBean");
|
||||
}
|
||||
|
||||
@Test
|
||||
void refreshForAotCanInstantiateBeanWithAutowiredApplicationContext() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(BeanD.class);
|
||||
context.refreshForAotProcessing();
|
||||
BeanD bean = context.getBean(BeanD.class);
|
||||
assertThat(bean.applicationContext).isSameAs(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
void refreshForAotCanInstantiateBeanWithFieldAutowiredApplicationContext() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(BeanB.class);
|
||||
context.refreshForAotProcessing();
|
||||
BeanB bean = context.getBean(BeanB.class);
|
||||
assertThat(bean.applicationContext).isSameAs(context);
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
@@ -506,6 +524,16 @@ class AnnotationConfigApplicationContextTests {
|
||||
|
||||
static class BeanC {}
|
||||
|
||||
static class BeanD {
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
public BeanD(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class NonInstantiatedFactoryBean implements FactoryBean<String> {
|
||||
|
||||
NonInstantiatedFactoryBean() {
|
||||
|
||||
@@ -23,10 +23,12 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.OS;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.AbstractFactoryBean;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
|
||||
@@ -407,6 +409,32 @@ class GenericApplicationContextTests {
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void refreshForAotInvokesBeanPostProcessorContractOnMergedBeanDefinitionPostProcessors() {
|
||||
MergedBeanDefinitionPostProcessor bpp = new MergedBeanDefinitionPostProcessor() {
|
||||
@Override
|
||||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||
beanDefinition.setAttribute("mbdppCalled", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
return (beanName.equals("test") ? "42" : bean);
|
||||
}
|
||||
};
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBeanDefinition("bpp", BeanDefinitionBuilder.rootBeanDefinition(
|
||||
MergedBeanDefinitionPostProcessor.class, () -> bpp)
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE).getBeanDefinition());
|
||||
AbstractBeanDefinition bd = BeanDefinitionBuilder.rootBeanDefinition(String.class)
|
||||
.addConstructorArgValue("value").getBeanDefinition();
|
||||
context.registerBeanDefinition("test", bd);
|
||||
context.refreshForAotProcessing();
|
||||
assertThat(context.getBeanFactory().getMergedBeanDefinition("test")
|
||||
.hasAttribute("mbdppCalled")).isTrue();
|
||||
assertThat(context.getBean("test")).isEqualTo("42");
|
||||
}
|
||||
|
||||
@Test
|
||||
void refreshForAotFailsOnAnActiveContext() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
|
||||
Reference in New Issue
Block a user