Don't implicitly filter all AOT processor beans
Update `BeanDefinitionMethodGeneratorFactory` to not implicitly filter AOT processor beans if they also implement `BeanRegistrationExcludeFilter`. Most AOT processor beans generate code that replaces themselves, so implicitly filtering them is the right thing to do. However, some beans may need to perform AOT processing and still get registered when the AOT processed application runs. These beans can now additionally implement `BeanRegistrationExcludeFilter` to signal that they should not be implicitly filtered. Closes gh-28526
This commit is contained in:
parent
efa8ffb728
commit
6f71328ba6
|
|
@ -114,6 +114,9 @@ class BeanDefinitionMethodGeneratorFactory {
|
||||||
|
|
||||||
private boolean isImplicitlyExcluded(RegisteredBean registeredBean) {
|
private boolean isImplicitlyExcluded(RegisteredBean registeredBean) {
|
||||||
Class<?> beanClass = registeredBean.getBeanClass();
|
Class<?> beanClass = registeredBean.getBeanClass();
|
||||||
|
if (BeanRegistrationExcludeFilter.class.isAssignableFrom(beanClass)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return BeanFactoryInitializationAotProcessor.class.isAssignableFrom(beanClass)
|
return BeanFactoryInitializationAotProcessor.class.isAssignableFrom(beanClass)
|
||||||
|| BeanRegistrationAotProcessor.class.isAssignableFrom(beanClass);
|
|| BeanRegistrationAotProcessor.class.isAssignableFrom(beanClass);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@ import org.springframework.aot.generate.GenerationContext;
|
||||||
* AOT contribution from a {@link BeanFactoryInitializationAotProcessor} used to
|
* AOT contribution from a {@link BeanFactoryInitializationAotProcessor} used to
|
||||||
* initialize a bean factory.
|
* initialize a bean factory.
|
||||||
*
|
*
|
||||||
|
* <p>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
|
* @author Phillip Webb
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
* @see BeanFactoryInitializationAotProcessor
|
* @see BeanFactoryInitializationAotProcessor
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,10 @@ import org.springframework.lang.Nullable;
|
||||||
* AOT processor that makes bean factory initialization contributions by
|
* AOT processor that makes bean factory initialization contributions by
|
||||||
* processing {@link ConfigurableListableBeanFactory} instances.
|
* processing {@link ConfigurableListableBeanFactory} instances.
|
||||||
*
|
*
|
||||||
|
* <p>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
|
* @author Phillip Webb
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
* @see BeanFactoryInitializationAotContribution
|
* @see BeanFactoryInitializationAotContribution
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package org.springframework.beans.factory.aot;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
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.BeanDefinitionBuilder;
|
||||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||||
import org.springframework.beans.factory.support.RegisteredBean;
|
import org.springframework.beans.factory.support.RegisteredBean;
|
||||||
|
|
@ -109,6 +110,34 @@ class BeanDefinitionMethodGeneratorFactoryTests {
|
||||||
.containsExactly(beanContribution, loaderContribution);
|
.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) {
|
private RegisteredBean registerTestBean(DefaultListableBeanFactory beanFactory) {
|
||||||
beanFactory.registerBeanDefinition("test", BeanDefinitionBuilder
|
beanFactory.registerBeanDefinition("test", BeanDefinitionBuilder
|
||||||
.rootBeanDefinition(TestBean.class).getBeanDefinition());
|
.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 {
|
static class InnerTestBean {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue