From 63b8e82c10587807ad6a108dbc6dba671b2d6f0e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 31 Aug 2016 13:26:25 +0100 Subject: [PATCH] Update OnBeanCondition to consider hierarchy for PARENTS search strategy Closes gh-6762 --- .../condition/OnBeanCondition.java | 4 +- .../ConditionalOnMissingBeanTests.java | 39 +++++++++++++ .../ConditionalOnSingleCandidateTests.java | 55 ++++++++++++++++++- 3 files changed, 95 insertions(+), 3 deletions(-) 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 1ec9a44aed3..37095420293 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -135,7 +135,7 @@ class OnBeanCondition extends SpringBootCondition implements ConfigurationCondit return Collections.emptyList(); } List beanNames = new ArrayList(); - boolean considerHierarchy = beans.getStrategy() == SearchStrategy.ALL; + boolean considerHierarchy = beans.getStrategy() != SearchStrategy.CURRENT; for (String type : beans.getTypes()) { beanNames.addAll(getBeanNamesForType(beanFactory, type, context.getClassLoader(), considerHierarchy)); 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 063d659632f..8fa6731fa22 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 @@ -250,6 +250,45 @@ public class ConditionalOnMissingBeanTests { is(equalTo(1))); } + @Test + public void grandparentIsConsideredWhenUsingParentsStrategy() { + 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, + OnBeanInParentsConfiguration.class); + child.refresh(); + assertThat(child.getBeansOfType(ExampleBean.class).size(), is(equalTo(1))); + child.close(); + parent.close(); + } + + @Test + public void currentContextIsIgnoredWhenUsingParentsStrategy() { + this.context.refresh(); + AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); + child.register(ExampleBeanConfiguration.class, + OnBeanInParentsConfiguration.class); + child.setParent(this.context); + child.refresh(); + assertThat(child.getBeansOfType(ExampleBean.class).size(), is(equalTo(2))); + } + + @Configuration + protected static class OnBeanInParentsConfiguration { + + @Bean + @ConditionalOnMissingBean(search = SearchStrategy.PARENTS) + 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 d8a20c5a894..5151a8f00b0 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 @@ -64,6 +64,46 @@ public class ConditionalOnSingleCandidateTests { assertEquals("foo", this.context.getBean("baz")); } + @Test + public void singleCandidateInParentsOneCandidateInCurrent() { + load(); + AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); + child.register(FooConfiguration.class, + OnBeanSingleCandidateInParentsConfiguration.class); + child.setParent(this.context); + child.refresh(); + assertFalse(child.containsBean("baz")); + child.close(); + } + + @Test + public void singleCandidateInParentsOneCandidateInParent() { + load(FooConfiguration.class); + AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); + child.register(OnBeanSingleCandidateInParentsConfiguration.class); + child.setParent(this.context); + child.refresh(); + assertTrue(child.containsBean("baz")); + assertEquals("foo", child.getBean("baz")); + child.close(); + } + + @Test + public void singleCandidateInParentsOneCandidateInGrandparent() { + load(FooConfiguration.class); + AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(); + parent.setParent(this.context); + parent.refresh(); + AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); + child.register(OnBeanSingleCandidateInParentsConfiguration.class); + child.setParent(parent); + child.refresh(); + assertTrue(child.containsBean("baz")); + assertEquals("foo", child.getBean("baz")); + child.close(); + parent.close(); + } + @Test public void singleCandidateMultipleCandidates() { load(FooConfiguration.class, BarConfiguration.class, @@ -121,7 +161,9 @@ public class ConditionalOnSingleCandidateTests { } private void load(Class... classes) { - this.context.register(classes); + if (classes.length > 0) { + this.context.register(classes); + } this.context.refresh(); } @@ -136,6 +178,17 @@ public class ConditionalOnSingleCandidateTests { } + @Configuration + @ConditionalOnSingleCandidate(value = String.class, search = SearchStrategy.PARENTS) + protected static class OnBeanSingleCandidateInParentsConfiguration { + + @Bean + public String baz(String s) { + return s; + } + + } + @Configuration @ConditionalOnSingleCandidate(value = String.class, type = "java.lang.String") protected static class OnBeanSingleCandidateTwoTypesConfiguration {