Skip to content

Commit

Permalink
Register test bean override infrastructure beans as singletons
Browse files Browse the repository at this point in the history
Prior to this commit, AOT processing failed for tests that made use of
test bean override features, since the Set<OverrideMetadata>
constructor argument configured in the bean definition for the
BeanOverrideBeanFactoryPostProcessor could not be handled by our AOT
support.

To address that, this commit registers test bean override
infrastructure beans as singletons instead of via bean definitions with
the infrastructure role.

See spring-projectsgh-32933
  • Loading branch information
sbrannen committed Sep 16, 2024
1 parent 13e175a commit b8f69eb
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,8 @@
package org.springframework.test.context.bean.override;

import java.util.Set;
import java.util.function.Consumer;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.MergedContextConfiguration;
Expand Down Expand Up @@ -57,43 +52,18 @@ class BeanOverrideContextCustomizer implements ContextCustomizer {

@Override
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
if (!(context instanceof BeanDefinitionRegistry registry)) {
throw new IllegalStateException("Cannot process bean overrides with an ApplicationContext " +
"that doesn't implement BeanDefinitionRegistry: " + context.getClass());
}
registerInfrastructure(registry);
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
BeanOverrideRegistrar beanOverrideRegistrar = new BeanOverrideRegistrar();
beanOverrideRegistrar.setBeanFactory(beanFactory);
beanFactory.registerSingleton(REGISTRAR_BEAN_NAME, beanOverrideRegistrar);
beanFactory.registerSingleton(EARLY_INFRASTRUCTURE_BEAN_NAME, new WrapEarlyBeanPostProcessor(beanOverrideRegistrar));
beanFactory.registerSingleton(INFRASTRUCTURE_BEAN_NAME, new BeanOverrideBeanFactoryPostProcessor(this.metadata, beanOverrideRegistrar));
}

Set<OverrideMetadata> getMetadata() {
return this.metadata;
}

private void registerInfrastructure(BeanDefinitionRegistry registry) {
addInfrastructureBeanDefinition(registry, BeanOverrideRegistrar.class, REGISTRAR_BEAN_NAME,
constructorArgs -> {});

RuntimeBeanReference registrarReference = new RuntimeBeanReference(REGISTRAR_BEAN_NAME);
addInfrastructureBeanDefinition(registry, WrapEarlyBeanPostProcessor.class, EARLY_INFRASTRUCTURE_BEAN_NAME,
constructorArgs -> constructorArgs.addIndexedArgumentValue(0, registrarReference));
addInfrastructureBeanDefinition(registry, BeanOverrideBeanFactoryPostProcessor.class, INFRASTRUCTURE_BEAN_NAME,
constructorArgs -> {
constructorArgs.addIndexedArgumentValue(0, this.metadata);
constructorArgs.addIndexedArgumentValue(1, registrarReference);
});
}

private void addInfrastructureBeanDefinition(BeanDefinitionRegistry registry,
Class<?> clazz, String beanName, Consumer<ConstructorArgumentValues> constructorArgumentsConsumer) {

if (!registry.containsBeanDefinition(beanName)) {
RootBeanDefinition definition = new RootBeanDefinition(clazz);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
ConstructorArgumentValues constructorArguments = definition.getConstructorArgumentValues();
constructorArgumentsConsumer.accept(constructorArguments);
registry.registerBeanDefinition(beanName, definition);
}
}

@Override
public boolean equals(Object other) {
if (other == this) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ void endToEndTestsForEntireSpringTestModule() {
runEndToEndTests(testClasses, false);
}

@Disabled("Comment out to run @TestBean integration tests in AOT mode")
@Test
void endToEndTestsForTestBeanOverrideTestClasses() {
List<Class<?>> testClasses = List.of(
Expand Down

0 comments on commit b8f69eb

Please sign in to comment.