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) {
if (Boolean.TRUE.equals(registeredBean.getMergedBeanDefinition()
.getAttribute(BeanRegistrationAotProcessor.IGNORE_REGISTRATION_ATTRIBUTE))) {
return true;
}
Class<?> beanClass = registeredBean.getBeanClass();
if (BeanFactoryInitializationAotProcessor.class.isAssignableFrom(beanClass)) {
return true;

View File

@ -49,6 +49,15 @@ import org.springframework.lang.Nullable;
@FunctionalInterface
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
* return a contribution or {@code null}.

View File

@ -36,6 +36,7 @@ import static org.mockito.Mockito.mock;
* Tests for {@link BeanDefinitionMethodGeneratorFactory}.
*
* @author Phillip Webb
* @author Stephane Nicoll
*/
class BeanDefinitionMethodGeneratorFactoryTests {
@ -58,6 +59,40 @@ class BeanDefinitionMethodGeneratorFactoryTests {
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
void getBeanDefinitionMethodGeneratorWhenExcludedByBeanRegistrationExcludeFilterReturnsNull() {
MockSpringFactoriesLoader springFactoriesLoader = new MockSpringFactoriesLoader();