Skip to content

Commit 104e941

Browse files
committed
Translate NullBean result to null for lookup method with bean name
Closes gh-25806
1 parent 62fef5a commit 104e941

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
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
@@ -1134,9 +1134,10 @@ protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd
11341134
* @see #getObjectForBeanInstance
11351135
*/
11361136
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
1137+
Object instance;
1138+
11371139
String outerBean = this.currentlyCreatedBean.get();
11381140
this.currentlyCreatedBean.set(beanName);
1139-
Object instance;
11401141
try {
11411142
instance = instanceSupplier.get();
11421143
}
@@ -1148,6 +1149,10 @@ protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String be
11481149
this.currentlyCreatedBean.remove();
11491150
}
11501151
}
1152+
1153+
if (instance == null) {
1154+
instance = new NullBean();
1155+
}
11511156
BeanWrapper bw = new BeanWrapperImpl(instance);
11521157
initBeanWrapper(bw);
11531158
return bw;

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 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.
@@ -286,8 +286,10 @@ public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp
286286
Assert.state(lo != null, "LookupOverride not found");
287287
Object[] argsToUse = (args.length > 0 ? args : null); // if no-arg, don't insist on args at all
288288
if (StringUtils.hasText(lo.getBeanName())) {
289-
return (argsToUse != null ? this.owner.getBean(lo.getBeanName(), argsToUse) :
289+
Object bean = (argsToUse != null ? this.owner.getBean(lo.getBeanName(), argsToUse) :
290290
this.owner.getBean(lo.getBeanName()));
291+
// Detect package-protected NullBean instance through equals(null) check
292+
return (bean.equals(null) ? null : bean);
291293
}
292294
else {
293295
return (argsToUse != null ? this.owner.getBean(method.getReturnType(), argsToUse) :

spring-beans/src/test/java/org/springframework/beans/factory/annotation/LookupAnnotationTests.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2020 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.
@@ -19,6 +19,7 @@
1919
import org.junit.Before;
2020
import org.junit.Test;
2121

22+
import org.springframework.beans.factory.config.BeanDefinition;
2223
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
2324
import org.springframework.beans.factory.support.RootBeanDefinition;
2425
import org.springframework.tests.sample.beans.TestBean;
@@ -110,10 +111,23 @@ public void testWithEarlyInjection() {
110111
assertSame(bean, beanFactory.getBean(BeanConsumer.class).abstractBean);
111112
}
112113

114+
@Test // gh-25806
115+
public void testWithNullBean() {
116+
RootBeanDefinition tbd = new RootBeanDefinition(TestBean.class, () -> null);
117+
tbd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
118+
beanFactory.registerBeanDefinition("testBean", tbd);
119+
120+
AbstractBean bean = beanFactory.getBean("beanConsumer", BeanConsumer.class).abstractBean;
121+
assertNotNull(bean);
122+
Object expected = bean.get();
123+
assertNull(expected);
124+
assertSame(bean, beanFactory.getBean(BeanConsumer.class).abstractBean);
125+
}
126+
113127

114128
public static abstract class AbstractBean {
115129

116-
@Lookup
130+
@Lookup("testBean")
117131
public abstract TestBean get();
118132

119133
@Lookup

0 commit comments

Comments
 (0)