diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactory.java index f4b741394cb..c8961659b10 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactory.java @@ -114,6 +114,9 @@ class BeanDefinitionMethodGeneratorFactory { private boolean isImplicitlyExcluded(RegisteredBean registeredBean) { Class> beanClass = registeredBean.getBeanClass(); + if (BeanRegistrationExcludeFilter.class.isAssignableFrom(beanClass)) { + return false; + } return BeanFactoryInitializationAotProcessor.class.isAssignableFrom(beanClass) || BeanRegistrationAotProcessor.class.isAssignableFrom(beanClass); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanFactoryInitializationAotContribution.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanFactoryInitializationAotContribution.java index 7d3b497e9de..2cfffc4a87b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanFactoryInitializationAotContribution.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanFactoryInitializationAotContribution.java @@ -22,6 +22,10 @@ import org.springframework.aot.generate.GenerationContext; * AOT contribution from a {@link BeanFactoryInitializationAotProcessor} used to * initialize a bean factory. * + *
Note: Beans implementing interface will not have registration methods + * generated during AOT processing unless they also implement + * {@link org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter}. + * * @author Phillip Webb * @since 6.0 * @see BeanFactoryInitializationAotProcessor diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanFactoryInitializationAotProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanFactoryInitializationAotProcessor.java index 9765e2c1f58..f48a53e1453 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanFactoryInitializationAotProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanFactoryInitializationAotProcessor.java @@ -23,6 +23,10 @@ import org.springframework.lang.Nullable; * AOT processor that makes bean factory initialization contributions by * processing {@link ConfigurableListableBeanFactory} instances. * + *
Note: Beans implementing interface will not have registration methods + * generated during AOT processing unless they also implement + * {@link org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter}. + * * @author Phillip Webb * @since 6.0 * @see BeanFactoryInitializationAotContribution diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactoryTests.java index e238a8570ff..247216a7c51 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactoryTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactoryTests.java @@ -18,6 +18,7 @@ package org.springframework.beans.factory.aot; import org.junit.jupiter.api.Test; +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.RegisteredBean; @@ -109,6 +110,34 @@ class BeanDefinitionMethodGeneratorFactoryTests { .containsExactly(beanContribution, loaderContribution); } + @Test + void getBeanDefinitionMethodGeneratorWhenRegisteredBeanIsAotProcessorFilteresBean() { + MockSpringFactoriesLoader springFactoriesLoader = new MockSpringFactoriesLoader(); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerBeanDefinition("test1", BeanDefinitionBuilder + .rootBeanDefinition(TestBeanFactoryInitializationAotProcessorBean.class).getBeanDefinition()); + RegisteredBean registeredBean1 = RegisteredBean.of(beanFactory, "test1"); + beanFactory.registerBeanDefinition("test2", BeanDefinitionBuilder + .rootBeanDefinition(TestBeanRegistrationAotProcessorBean.class).getBeanDefinition()); + RegisteredBean registeredBean2 = RegisteredBean.of(beanFactory, "test2"); + BeanDefinitionMethodGeneratorFactory methodGeneratorFactory = new BeanDefinitionMethodGeneratorFactory( + new AotFactoriesLoader(beanFactory, springFactoriesLoader)); + assertThat(methodGeneratorFactory.getBeanDefinitionMethodGenerator(registeredBean1, null)).isNull(); + assertThat(methodGeneratorFactory.getBeanDefinitionMethodGenerator(registeredBean2, null)).isNull(); + } + + @Test + void getBeanDefinitionMethodGeneratorWhenRegisteredBeanIsAotProcessorAndFilteresBeanBeanRegistrationExcludeFilterDoesNotFilterBean() { + MockSpringFactoriesLoader springFactoriesLoader = new MockSpringFactoriesLoader(); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerBeanDefinition("test", BeanDefinitionBuilder + .rootBeanDefinition(TestBeanRegistrationAotProcessorAndFilterBean.class).getBeanDefinition()); + RegisteredBean registeredBean1 = RegisteredBean.of(beanFactory, "test"); + BeanDefinitionMethodGeneratorFactory methodGeneratorFactory = new BeanDefinitionMethodGeneratorFactory( + new AotFactoriesLoader(beanFactory, springFactoriesLoader)); + assertThat(methodGeneratorFactory.getBeanDefinitionMethodGenerator(registeredBean1, null)).isNotNull(); + } + private RegisteredBean registerTestBean(DefaultListableBeanFactory beanFactory) { beanFactory.registerBeanDefinition("test", BeanDefinitionBuilder .rootBeanDefinition(TestBean.class).getBeanDefinition()); @@ -150,6 +179,35 @@ class BeanDefinitionMethodGeneratorFactoryTests { } + static class TestBeanFactoryInitializationAotProcessorBean implements BeanFactoryInitializationAotProcessor{ + + @Override + public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) { + return null; + } + + } + + static class TestBeanRegistrationAotProcessorBean implements BeanRegistrationAotProcessor { + + @Override + public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) { + return null; + } + + } + + static class TestBeanRegistrationAotProcessorAndFilterBean + extends TestBeanRegistrationAotProcessorBean + implements BeanRegistrationExcludeFilter { + + @Override + public boolean isExcluded(RegisteredBean registeredBean) { + return false; + } + + } + static class InnerTestBean { }