Skip to content

Commit 2be5544

Browse files
committed
Introduce SearchStrategy.ANCESTORS as a replacement for .PARENTS
Closes gh-6763
1 parent 5d87612 commit 2be5544

File tree

5 files changed

+104
-3
lines changed

5 files changed

+104
-3
lines changed

spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcChildContextConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public void handlerMapping(MvcEndpoints endpoints,
151151

152152
@Configuration
153153
@ConditionalOnClass({ EnableWebSecurity.class, Filter.class })
154-
@ConditionalOnBean(name = "springSecurityFilterChain", search = SearchStrategy.PARENTS)
154+
@ConditionalOnBean(name = "springSecurityFilterChain", search = SearchStrategy.ANCESTORS)
155155
public static class EndpointWebMvcChildContextSecurityConfiguration {
156156

157157
@Bean

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnBeanCondition.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,12 @@ else if (!hasSingleAutowireCandidate(context.getBeanFactory(), matching,
123123
return ConditionOutcome.match(matchMessage);
124124
}
125125

126+
@SuppressWarnings("deprecation")
126127
private List<String> getMatchingBeans(ConditionContext context,
127128
BeanSearchSpec beans) {
128129
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
129-
if (beans.getStrategy() == SearchStrategy.PARENTS) {
130+
if (beans.getStrategy() == SearchStrategy.PARENTS
131+
|| beans.getStrategy() == SearchStrategy.ANCESTORS) {
130132
BeanFactory parent = beanFactory.getParentBeanFactory();
131133
Assert.isInstanceOf(ConfigurableListableBeanFactory.class, parent,
132134
"Unable to use SearchStrategy.PARENTS");

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/SearchStrategy.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,15 @@ public enum SearchStrategy {
3030

3131
/**
3232
* Search all parents and ancestors, but not the current context.
33+
*
34+
* @deprecated since 1.5 in favor of {@link SearchStrategy#ANCESTORS}
3335
*/
34-
PARENTS,
36+
@Deprecated PARENTS,
37+
38+
/**
39+
* Search all ancestors, but not the current context.
40+
*/
41+
ANCESTORS,
3542

3643
/**
3744
* Search the entire hierarchy.

spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnMissingBeanTests.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,23 @@ public void grandparentIsConsideredWhenUsingParentsStrategy() {
274274
parent.close();
275275
}
276276

277+
@Test
278+
public void grandparentIsConsideredWhenUsingAncestorsStrategy() {
279+
this.context.register(ExampleBeanConfiguration.class);
280+
this.context.refresh();
281+
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
282+
parent.setParent(this.context);
283+
parent.refresh();
284+
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
285+
child.setParent(parent);
286+
child.register(ExampleBeanConfiguration.class,
287+
OnBeanInAncestorsConfiguration.class);
288+
child.refresh();
289+
assertThat(child.getBeansOfType(ExampleBean.class)).hasSize(1);
290+
child.close();
291+
parent.close();
292+
}
293+
277294
@Test
278295
public void currentContextIsIgnoredWhenUsingParentsStrategy() {
279296
this.context.refresh();
@@ -285,9 +302,21 @@ public void currentContextIsIgnoredWhenUsingParentsStrategy() {
285302
assertThat(child.getBeansOfType(ExampleBean.class)).hasSize(2);
286303
}
287304

305+
@Test
306+
public void currentContextIsIgnoredWhenUsingAncestorsStrategy() {
307+
this.context.refresh();
308+
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
309+
child.register(ExampleBeanConfiguration.class,
310+
OnBeanInAncestorsConfiguration.class);
311+
child.setParent(this.context);
312+
child.refresh();
313+
assertThat(child.getBeansOfType(ExampleBean.class)).hasSize(2);
314+
}
315+
288316
@Configuration
289317
protected static class OnBeanInParentsConfiguration {
290318

319+
@SuppressWarnings("deprecation")
291320
@Bean
292321
@ConditionalOnMissingBean(search = SearchStrategy.PARENTS)
293322
public ExampleBean exampleBean2() {
@@ -296,6 +325,17 @@ public ExampleBean exampleBean2() {
296325

297326
}
298327

328+
@Configuration
329+
protected static class OnBeanInAncestorsConfiguration {
330+
331+
@Bean
332+
@ConditionalOnMissingBean(search = SearchStrategy.ANCESTORS)
333+
public ExampleBean exampleBean2() {
334+
return new ExampleBean("test");
335+
}
336+
337+
}
338+
299339
@Configuration
300340
@ConditionalOnMissingBean(name = "foo")
301341
protected static class OnBeanNameConfiguration {

spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnSingleCandidateTests.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,46 @@ public void singleCandidateInParentsOneCandidateInGrandparent() {
102102
parent.close();
103103
}
104104

105+
@Test
106+
public void singleCandidateInAncestorsOneCandidateInCurrent() {
107+
load();
108+
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
109+
child.register(FooConfiguration.class,
110+
OnBeanSingleCandidateInAncestorsConfiguration.class);
111+
child.setParent(this.context);
112+
child.refresh();
113+
assertThat(child.containsBean("baz")).isFalse();
114+
child.close();
115+
}
116+
117+
@Test
118+
public void singleCandidateInAncestorsOneCandidateInParent() {
119+
load(FooConfiguration.class);
120+
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
121+
child.register(OnBeanSingleCandidateInAncestorsConfiguration.class);
122+
child.setParent(this.context);
123+
child.refresh();
124+
assertThat(child.containsBean("baz")).isTrue();
125+
assertThat(child.getBean("baz")).isEqualTo("foo");
126+
child.close();
127+
}
128+
129+
@Test
130+
public void singleCandidateInAncestorsOneCandidateInGrandparent() {
131+
load(FooConfiguration.class);
132+
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
133+
parent.setParent(this.context);
134+
parent.refresh();
135+
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext();
136+
child.register(OnBeanSingleCandidateInAncestorsConfiguration.class);
137+
child.setParent(parent);
138+
child.refresh();
139+
assertThat(child.containsBean("baz")).isTrue();
140+
assertThat(child.getBean("baz")).isEqualTo("foo");
141+
child.close();
142+
parent.close();
143+
}
144+
105145
@Test
106146
public void singleCandidateMultipleCandidates() {
107147
load(FooConfiguration.class, BarConfiguration.class,
@@ -176,6 +216,7 @@ public String baz(String s) {
176216

177217
}
178218

219+
@SuppressWarnings("deprecation")
179220
@Configuration
180221
@ConditionalOnSingleCandidate(value = String.class, search = SearchStrategy.PARENTS)
181222
protected static class OnBeanSingleCandidateInParentsConfiguration {
@@ -187,6 +228,17 @@ public String baz(String s) {
187228

188229
}
189230

231+
@Configuration
232+
@ConditionalOnSingleCandidate(value = String.class, search = SearchStrategy.ANCESTORS)
233+
protected static class OnBeanSingleCandidateInAncestorsConfiguration {
234+
235+
@Bean
236+
public String baz(String s) {
237+
return s;
238+
}
239+
240+
}
241+
190242
@Configuration
191243
@ConditionalOnSingleCandidate(value = String.class, type = "java.lang.String")
192244
protected static class OnBeanSingleCandidateTwoTypesConfiguration {

0 commit comments

Comments
 (0)