Exclude bean definition from AOT processing using an attribute

This commits allows a particular bean definition to be excluded from
AOT processing using an attribute.

If BeanRegistrationAotProcessor#IGNORE_REGISTRATION_ATTRIBUTE is set
to `true`, then the bean definition is excluded. This complement the
existing BeanRegistrationExcludeFilter capability.

Closes gh-33243
This commit is contained in:
Stéphane Nicoll 2024-07-21 13:41:30 +02:00
parent bbfc3364e1
commit e741d6edbb
3 changed files with 48 additions and 0 deletions

View File

@ -133,6 +133,10 @@ class BeanDefinitionMethodGeneratorFactory {
} }
private boolean isImplicitlyExcluded(RegisteredBean registeredBean) { private boolean isImplicitlyExcluded(RegisteredBean registeredBean) {
if (Boolean.TRUE.equals(registeredBean.getMergedBeanDefinition()
.getAttribute(BeanRegistrationAotProcessor.IGNORE_REGISTRATION_ATTRIBUTE))) {
return true;
}
Class<?> beanClass = registeredBean.getBeanClass(); Class<?> beanClass = registeredBean.getBeanClass();
if (BeanFactoryInitializationAotProcessor.class.isAssignableFrom(beanClass)) { if (BeanFactoryInitializationAotProcessor.class.isAssignableFrom(beanClass)) {
return true; return true;

View File

@ -49,6 +49,15 @@ import org.springframework.lang.Nullable;
@FunctionalInterface @FunctionalInterface
public interface BeanRegistrationAotProcessor { public interface BeanRegistrationAotProcessor {
/**
* The name of an attribute that can be
* {@link org.springframework.core.AttributeAccessor#setAttribute set} on a
* {@link org.springframework.beans.factory.config.BeanDefinition} to signal
* that its registration should not be processed.
* @since 6.2
*/
String IGNORE_REGISTRATION_ATTRIBUTE = "aotProcessingIgnoreRegistration";
/** /**
* Process the given {@link RegisteredBean} instance ahead-of-time and * Process the given {@link RegisteredBean} instance ahead-of-time and
* return a contribution or {@code null}. * return a contribution or {@code null}.

View File

@ -36,6 +36,7 @@ import static org.mockito.Mockito.mock;
* Tests for {@link BeanDefinitionMethodGeneratorFactory}. * Tests for {@link BeanDefinitionMethodGeneratorFactory}.
* *
* @author Phillip Webb * @author Phillip Webb
* @author Stephane Nicoll
*/ */
class BeanDefinitionMethodGeneratorFactoryTests { class BeanDefinitionMethodGeneratorFactoryTests {
@ -58,6 +59,40 @@ class BeanDefinitionMethodGeneratorFactoryTests {
AotServices.factories(loader))); AotServices.factories(loader)));
} }
@Test
void getBeanDefinitionMethodGeneratorWhenExcludedByBeanDefinitionAttributeReturnsNull() {
MockSpringFactoriesLoader springFactoriesLoader = new MockSpringFactoriesLoader();
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
RegisteredBean registeredBean = registerTestBean(beanFactory);
registeredBean.getMergedBeanDefinition().setAttribute(
BeanRegistrationAotProcessor.IGNORE_REGISTRATION_ATTRIBUTE, true);
BeanDefinitionMethodGeneratorFactory methodGeneratorFactory = new BeanDefinitionMethodGeneratorFactory(
AotServices.factoriesAndBeans(springFactoriesLoader, beanFactory));
assertThat(methodGeneratorFactory.getBeanDefinitionMethodGenerator(registeredBean)).isNull();
}
@Test
void getBeanDefinitionMethodGeneratorWhenBeanDefinitionAttributeSetToFalseDoesNotFilterBean() {
MockSpringFactoriesLoader springFactoriesLoader = new MockSpringFactoriesLoader();
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
RegisteredBean registeredBean = registerTestBean(beanFactory);
registeredBean.getMergedBeanDefinition().setAttribute(
BeanRegistrationAotProcessor.IGNORE_REGISTRATION_ATTRIBUTE, false);
BeanDefinitionMethodGeneratorFactory methodGeneratorFactory = new BeanDefinitionMethodGeneratorFactory(
AotServices.factoriesAndBeans(springFactoriesLoader, beanFactory));
assertThat(methodGeneratorFactory.getBeanDefinitionMethodGenerator(registeredBean)).isNotNull();
}
@Test
void getBeanDefinitionMethodGeneratorWhenBeanDefinitionAttributeIsNotSetDoesNotFilterBean() {
MockSpringFactoriesLoader springFactoriesLoader = new MockSpringFactoriesLoader();
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
RegisteredBean registeredBean = registerTestBean(beanFactory);
BeanDefinitionMethodGeneratorFactory methodGeneratorFactory = new BeanDefinitionMethodGeneratorFactory(
AotServices.factoriesAndBeans(springFactoriesLoader, beanFactory));
assertThat(methodGeneratorFactory.getBeanDefinitionMethodGenerator(registeredBean)).isNotNull();
}
@Test @Test
void getBeanDefinitionMethodGeneratorWhenExcludedByBeanRegistrationExcludeFilterReturnsNull() { void getBeanDefinitionMethodGeneratorWhenExcludedByBeanRegistrationExcludeFilterReturnsNull() {
MockSpringFactoriesLoader springFactoriesLoader = new MockSpringFactoriesLoader(); MockSpringFactoriesLoader springFactoriesLoader = new MockSpringFactoriesLoader();