diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessor.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessor.java index 5e3a47031c..980efe5dff 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessor.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessor.java @@ -17,8 +17,10 @@ package org.springframework.boot.autoconfigure; import java.util.Arrays; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; import org.springframework.beans.factory.BeanFactory; @@ -33,8 +35,8 @@ import org.springframework.util.StringUtils; /** * Abstract base class for a {@link BeanFactoryPostProcessor} that can be used to - * dynamically declare that all beans of a specific type should depend on one or more - * specific beans. + * dynamically declare that all beans of a specific type should depend on specific other + * beans identified by name or type. * * @author Marcel Overdijk * @author Dave Syer @@ -50,27 +52,29 @@ public abstract class AbstractDependsOnBeanFactoryPostProcessor implements BeanF private final Class> factoryBeanClass; - private final Object[] dependsOn; + private final Function> dependsOn; protected AbstractDependsOnBeanFactoryPostProcessor(Class beanClass, Class> factoryBeanClass, String... dependsOn) { this.beanClass = beanClass; this.factoryBeanClass = factoryBeanClass; - this.dependsOn = dependsOn; + this.dependsOn = (beanFactory) -> new HashSet<>(Arrays.asList(dependsOn)); } /** * Create an instance with target bean and factory bean classes and dependency types. * @param beanClass target bean class * @param factoryBeanClass target factory bean class - * @param dependsOn dependency types - * @since 2.2.0 + * @param dependencyTypes dependency types + * @since 2.1.7 */ protected AbstractDependsOnBeanFactoryPostProcessor(Class beanClass, - Class> factoryBeanClass, Class... dependsOn) { + Class> factoryBeanClass, Class... dependencyTypes) { this.beanClass = beanClass; this.factoryBeanClass = factoryBeanClass; - this.dependsOn = dependsOn; + this.dependsOn = (beanFactory) -> Arrays.stream(dependencyTypes) + .flatMap((dependencyType) -> getBeanNames(beanFactory, dependencyType).stream()) + .collect(Collectors.toSet()); } /** @@ -86,11 +90,11 @@ public abstract class AbstractDependsOnBeanFactoryPostProcessor implements BeanF /** * Create an instance with target bean class and dependency types. * @param beanClass target bean class - * @param dependsOn dependency types - * @since 2.2.0 + * @param dependencyTypes dependency types + * @since 2.1.7 */ - protected AbstractDependsOnBeanFactoryPostProcessor(Class beanClass, Class... dependsOn) { - this(beanClass, null, dependsOn); + protected AbstractDependsOnBeanFactoryPostProcessor(Class beanClass, Class... dependencyTypes) { + this(beanClass, null, dependencyTypes); } @Override @@ -98,22 +102,13 @@ public abstract class AbstractDependsOnBeanFactoryPostProcessor implements BeanF for (String beanName : getBeanNames(beanFactory)) { BeanDefinition definition = getBeanDefinition(beanName, beanFactory); String[] dependencies = definition.getDependsOn(); - for (String bean : getDependsOn(beanFactory)) { - dependencies = StringUtils.addStringToArray(dependencies, bean); + for (String dependencyName : this.dependsOn.apply(beanFactory)) { + dependencies = StringUtils.addStringToArray(dependencies, dependencyName); } definition.setDependsOn(dependencies); } } - private Set getDependsOn(ListableBeanFactory beanFactory) { - if (this.dependsOn instanceof Class[]) { - return Arrays.stream(((Class[]) this.dependsOn)) - .flatMap((beanClass) -> getBeanNames(beanFactory, beanClass).stream()) - .collect(Collectors.toCollection(LinkedHashSet::new)); - } - return Arrays.stream(this.dependsOn).map(String::valueOf).collect(Collectors.toCollection(LinkedHashSet::new)); - } - private Set getBeanNames(ListableBeanFactory beanFactory) { Set names = getBeanNames(beanFactory, this.beanClass); if (this.factoryBeanClass != null) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessorTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessorTests.java index 660029efb5..f379fa97dc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessorTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessorTests.java @@ -16,7 +16,7 @@ package org.springframework.boot.autoconfigure; -import org.junit.jupiter.api.Test; +import org.junit.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.FactoryBean; @@ -36,27 +36,27 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Dmytro Nosan */ -class AbstractDependsOnBeanFactoryPostProcessorTests { +public class AbstractDependsOnBeanFactoryPostProcessorTests { private ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withUserConfiguration(FooBarConfiguration.class); @Test - void fooBeansShouldDependOnBarBeanNames() { + public void fooBeansShouldDependOnBarBeanNames() { this.contextRunner .withUserConfiguration(FooDependsOnBarNamePostProcessor.class, FooBarFactoryBeanConfiguration.class) .run(this::assertThatFooDependsOnBar); } @Test - void fooBeansShouldDependOnBarBeanTypes() { + public void fooBeansShouldDependOnBarBeanTypes() { this.contextRunner .withUserConfiguration(FooDependsOnBarTypePostProcessor.class, FooBarFactoryBeanConfiguration.class) .run(this::assertThatFooDependsOnBar); } @Test - void fooBeansShouldDependOnBarBeanNamesParentContext() { + public void fooBeansShouldDependOnBarBeanNamesParentContext() { try (AnnotationConfigApplicationContext parentContext = new AnnotationConfigApplicationContext( FooBarFactoryBeanConfiguration.class)) { this.contextRunner.withUserConfiguration(FooDependsOnBarNamePostProcessor.class).withParent(parentContext) @@ -65,7 +65,7 @@ class AbstractDependsOnBeanFactoryPostProcessorTests { } @Test - void fooBeansShouldDependOnBarBeanTypesParentContext() { + public void fooBeansShouldDependOnBarBeanTypesParentContext() { try (AnnotationConfigApplicationContext parentContext = new AnnotationConfigApplicationContext( FooBarFactoryBeanConfiguration.class)) { this.contextRunner.withUserConfiguration(FooDependsOnBarTypePostProcessor.class).withParent(parentContext) @@ -101,7 +101,7 @@ class AbstractDependsOnBeanFactoryPostProcessorTests { } - @Configuration(proxyBeanMethods = false) + @Configuration static class FooBarFactoryBeanConfiguration { @Bean @@ -116,7 +116,7 @@ class AbstractDependsOnBeanFactoryPostProcessorTests { } - @Configuration(proxyBeanMethods = false) + @Configuration static class FooBarConfiguration { @Bean