Skip to content

Commit 28f7b26

Browse files
committed
Null-returning instance supplier resolves to NullBean
Issue: SPR-17057
1 parent f855311 commit 28f7b26

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1148,9 +1148,10 @@ protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd
11481148
* @see #getObjectForBeanInstance
11491149
*/
11501150
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
1151+
Object instance;
1152+
11511153
String outerBean = this.currentlyCreatedBean.get();
11521154
this.currentlyCreatedBean.set(beanName);
1153-
Object instance;
11541155
try {
11551156
instance = instanceSupplier.get();
11561157
}
@@ -1162,6 +1163,10 @@ protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String be
11621163
this.currentlyCreatedBean.remove();
11631164
}
11641165
}
1166+
1167+
if (instance == null) {
1168+
instance = new NullBean();
1169+
}
11651170
BeanWrapper bw = new BeanWrapperImpl(instance);
11661171
initBeanWrapper(bw);
11671172
return bw;

spring-context/src/test/java/org/springframework/context/annotation/AnnotationConfigApplicationContextTests.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,8 +29,9 @@
2929
import org.springframework.context.annotation6.ComponentForScanning;
3030
import org.springframework.context.annotation6.ConfigForScanning;
3131
import org.springframework.context.annotation6.Jsr330NamedForScanning;
32+
import org.springframework.util.ObjectUtils;
3233

33-
import static java.lang.String.format;
34+
import static java.lang.String.*;
3435
import static org.hamcrest.Matchers.*;
3536
import static org.junit.Assert.*;
3637
import static org.springframework.util.StringUtils.*;
@@ -210,6 +211,22 @@ public void individualNamedBeanWithSupplierAndCustomizer() {
210211
assertSame(context, context.getBean("b", BeanB.class).applicationContext);
211212
}
212213

214+
@Test
215+
public void individualBeanWithNullReturningSupplier() {
216+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
217+
context.registerBean("a", BeanA.class, () -> null);
218+
context.registerBean("b", BeanB.class, BeanB::new);
219+
context.registerBean("c", BeanC.class, BeanC::new);
220+
context.refresh();
221+
222+
assertTrue(ObjectUtils.containsElement(context.getBeanNamesForType(BeanA.class), "a"));
223+
assertTrue(ObjectUtils.containsElement(context.getBeanNamesForType(BeanB.class), "b"));
224+
assertTrue(ObjectUtils.containsElement(context.getBeanNamesForType(BeanC.class), "c"));
225+
assertTrue(context.getBeansOfType(BeanA.class).isEmpty());
226+
assertSame(context.getBean(BeanB.class), context.getBeansOfType(BeanB.class).values().iterator().next());
227+
assertSame(context.getBean(BeanC.class), context.getBeansOfType(BeanC.class).values().iterator().next());
228+
}
229+
213230
@Test
214231
public void individualBeanWithSpecifiedConstructorArguments() {
215232
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

0 commit comments

Comments
 (0)