Allow registration of bean factory contributors via spring.factories

Closes gh-28342
This commit is contained in:
Stephane Nicoll
2022-04-14 15:10:01 +02:00
parent 8b97c2dc9d
commit 7820804bf6
4 changed files with 65 additions and 3 deletions

View File

@@ -18,6 +18,8 @@ package org.springframework.context.generator;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URL;
import java.util.Enumeration;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -148,6 +150,27 @@ class ApplicationContextAotGeneratorTests {
""");
}
@Test
void generateApplicationContextLoadsBeanFactoryContributors() {
GeneratedTypeContext generationContext = createGenerationContext();
ApplicationContextAotGenerator generator = new ApplicationContextAotGenerator();
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.setClassLoader(
new TestSpringFactoriesClassLoader("bean-factory-contributors.factories"));
generator.generateApplicationContext(applicationContext, generationContext);
assertThat(write(generationContext.getMainGeneratedType())).contains("""
public class Test implements ApplicationContextInitializer<GenericApplicationContext> {
@Override
public void initialize(GenericApplicationContext context) {
// infrastructure
DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
// Test
}
}
""");
}
@Test
void generateApplicationContextApplyContributionAsIsWithNewLineAtTheEnd() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
@@ -211,8 +234,7 @@ class ApplicationContextAotGeneratorTests {
GeneratedTypeContext generationContext = createGenerationContext();
GenericApplicationContext applicationContext = new GenericApplicationContext();
DefaultListableBeanFactory beanFactory = applicationContext.getDefaultListableBeanFactory();
@SuppressWarnings("unchecked")
BiPredicate<String, BeanDefinition> excludeFilter = mock(BiPredicate.class);
BiPredicate<String, BeanDefinition> excludeFilter = mockExcludeFilter();
given(excludeFilter.test(eq("bean1"), any(BeanDefinition.class))).willReturn(Boolean.FALSE);
given(excludeFilter.test(eq("bean2"), any(BeanDefinition.class))).willReturn(Boolean.TRUE);
applicationContext.registerBeanDefinition("bean2", new RootBeanDefinition(SimpleComponent.class));
@@ -228,6 +250,11 @@ class ApplicationContextAotGeneratorTests {
}
@SuppressWarnings("unchecked")
private BiPredicate<String, BeanDefinition> mockExcludeFilter() {
return mock(BiPredicate.class);
}
@SuppressWarnings("rawtypes")
private void compile(GenericApplicationContext applicationContext, Consumer<ApplicationContextInitializer> initializer) {
DefaultGeneratedTypeContext generationContext = createGenerationContext();
@@ -306,6 +333,15 @@ class ApplicationContextAotGeneratorTests {
}
static class TextAotContributingBeanFactoryPostProcessor implements AotContributingBeanFactoryPostProcessor {
@Override
public BeanFactoryContribution contribute(ConfigurableListableBeanFactory beanFactory) {
return initialization -> initialization.contribute(code -> code.add("// Test\n"));
}
}
static class NoOpAotContributingBeanFactoryPostProcessor implements AotContributingBeanFactoryPostProcessor {
@Override
@@ -352,4 +388,23 @@ class ApplicationContextAotGeneratorTests {
}
static class TestSpringFactoriesClassLoader extends ClassLoader {
private final String factoriesName;
TestSpringFactoriesClassLoader(String factoriesName) {
super(RuntimeHintsPostProcessorTests.class.getClassLoader());
this.factoriesName = factoriesName;
}
@Override
public Enumeration<URL> getResources(String name) throws IOException {
if ("META-INF/spring.factories".equals(name)) {
return super.getResources("org/springframework/context/generator/aot/" + this.factoriesName);
}
return super.getResources(name);
}
}
}