From 2be554456ecde05362240ba351c90cebd507f6f5 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 28 Nov 2016 15:39:05 +0000 Subject: [PATCH] Introduce SearchStrategy.ANCESTORS as a replacement for .PARENTS Closes gh-6763 --- ...dpointWebMvcChildContextConfiguration.java | 2 +- .../condition/OnBeanCondition.java | 4 +- .../condition/SearchStrategy.java | 9 +++- .../ConditionalOnMissingBeanTests.java | 40 ++++++++++++++ .../ConditionalOnSingleCandidateTests.java | 52 +++++++++++++++++++ 5 files changed, 104 insertions(+), 3 deletions(-) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcChildContextConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcChildContextConfiguration.java index d47c25f44f..0b6dbd877f 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcChildContextConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcChildContextConfiguration.java @@ -151,7 +151,7 @@ public class EndpointWebMvcChildContextConfiguration { @Configuration @ConditionalOnClass({ EnableWebSecurity.class, Filter.class }) - @ConditionalOnBean(name = "springSecurityFilterChain", search = SearchStrategy.PARENTS) + @ConditionalOnBean(name = "springSecurityFilterChain", search = SearchStrategy.ANCESTORS) public static class EndpointWebMvcChildContextSecurityConfiguration { @Bean diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnBeanCondition.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnBeanCondition.java index 5ec455115b..1f4d994c2b 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnBeanCondition.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnBeanCondition.java @@ -123,10 +123,12 @@ class OnBeanCondition extends SpringBootCondition implements ConfigurationCondit return ConditionOutcome.match(matchMessage); } + @SuppressWarnings("deprecation") private List getMatchingBeans(ConditionContext context, BeanSearchSpec beans) { ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); - if (beans.getStrategy() == SearchStrategy.PARENTS) { + if (beans.getStrategy() == SearchStrategy.PARENTS + || beans.getStrategy() == SearchStrategy.ANCESTORS) { BeanFactory parent = beanFactory.getParentBeanFactory(); Assert.isInstanceOf(ConfigurableListableBeanFactory.class, parent, "Unable to use SearchStrategy.PARENTS"); diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/SearchStrategy.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/SearchStrategy.java index 74be38e6fa..2379fdb4a0 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/SearchStrategy.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/SearchStrategy.java @@ -30,8 +30,15 @@ public enum SearchStrategy { /** * Search all parents and ancestors, but not the current context. + * + * @deprecated since 1.5 in favor of {@link SearchStrategy#ANCESTORS} */ - PARENTS, + @Deprecated PARENTS, + + /** + * Search all ancestors, but not the current context. + */ + ANCESTORS, /** * Search the entire hierarchy. diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnMissingBeanTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnMissingBeanTests.java index ef48fa8e6b..8706fbd50d 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnMissingBeanTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnMissingBeanTests.java @@ -274,6 +274,23 @@ public class ConditionalOnMissingBeanTests { parent.close(); } + @Test + public void grandparentIsConsideredWhenUsingAncestorsStrategy() { + this.context.register(ExampleBeanConfiguration.class); + this.context.refresh(); + AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(); + parent.setParent(this.context); + parent.refresh(); + AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); + child.setParent(parent); + child.register(ExampleBeanConfiguration.class, + OnBeanInAncestorsConfiguration.class); + child.refresh(); + assertThat(child.getBeansOfType(ExampleBean.class)).hasSize(1); + child.close(); + parent.close(); + } + @Test public void currentContextIsIgnoredWhenUsingParentsStrategy() { this.context.refresh(); @@ -285,9 +302,21 @@ public class ConditionalOnMissingBeanTests { assertThat(child.getBeansOfType(ExampleBean.class)).hasSize(2); } + @Test + public void currentContextIsIgnoredWhenUsingAncestorsStrategy() { + this.context.refresh(); + AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); + child.register(ExampleBeanConfiguration.class, + OnBeanInAncestorsConfiguration.class); + child.setParent(this.context); + child.refresh(); + assertThat(child.getBeansOfType(ExampleBean.class)).hasSize(2); + } + @Configuration protected static class OnBeanInParentsConfiguration { + @SuppressWarnings("deprecation") @Bean @ConditionalOnMissingBean(search = SearchStrategy.PARENTS) public ExampleBean exampleBean2() { @@ -296,6 +325,17 @@ public class ConditionalOnMissingBeanTests { } + @Configuration + protected static class OnBeanInAncestorsConfiguration { + + @Bean + @ConditionalOnMissingBean(search = SearchStrategy.ANCESTORS) + public ExampleBean exampleBean2() { + return new ExampleBean("test"); + } + + } + @Configuration @ConditionalOnMissingBean(name = "foo") protected static class OnBeanNameConfiguration { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnSingleCandidateTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnSingleCandidateTests.java index 1877b70fbb..27c2f5ebd9 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnSingleCandidateTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnSingleCandidateTests.java @@ -102,6 +102,46 @@ public class ConditionalOnSingleCandidateTests { parent.close(); } + @Test + public void singleCandidateInAncestorsOneCandidateInCurrent() { + load(); + AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); + child.register(FooConfiguration.class, + OnBeanSingleCandidateInAncestorsConfiguration.class); + child.setParent(this.context); + child.refresh(); + assertThat(child.containsBean("baz")).isFalse(); + child.close(); + } + + @Test + public void singleCandidateInAncestorsOneCandidateInParent() { + load(FooConfiguration.class); + AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); + child.register(OnBeanSingleCandidateInAncestorsConfiguration.class); + child.setParent(this.context); + child.refresh(); + assertThat(child.containsBean("baz")).isTrue(); + assertThat(child.getBean("baz")).isEqualTo("foo"); + child.close(); + } + + @Test + public void singleCandidateInAncestorsOneCandidateInGrandparent() { + load(FooConfiguration.class); + AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(); + parent.setParent(this.context); + parent.refresh(); + AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); + child.register(OnBeanSingleCandidateInAncestorsConfiguration.class); + child.setParent(parent); + child.refresh(); + assertThat(child.containsBean("baz")).isTrue(); + assertThat(child.getBean("baz")).isEqualTo("foo"); + child.close(); + parent.close(); + } + @Test public void singleCandidateMultipleCandidates() { load(FooConfiguration.class, BarConfiguration.class, @@ -176,6 +216,7 @@ public class ConditionalOnSingleCandidateTests { } + @SuppressWarnings("deprecation") @Configuration @ConditionalOnSingleCandidate(value = String.class, search = SearchStrategy.PARENTS) protected static class OnBeanSingleCandidateInParentsConfiguration { @@ -187,6 +228,17 @@ public class ConditionalOnSingleCandidateTests { } + @Configuration + @ConditionalOnSingleCandidate(value = String.class, search = SearchStrategy.ANCESTORS) + protected static class OnBeanSingleCandidateInAncestorsConfiguration { + + @Bean + public String baz(String s) { + return s; + } + + } + @Configuration @ConditionalOnSingleCandidate(value = String.class, type = "java.lang.String") protected static class OnBeanSingleCandidateTwoTypesConfiguration {