Skip to content

Commit d9e261a

Browse files
committed
Enforce backwards compatibility for null bean in shortcut code path
Closes gh-34929
1 parent 15d1455 commit d9e261a

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1679,7 +1679,12 @@ public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable Str
16791679
if (autowiredBeanNames != null) {
16801680
autowiredBeanNames.add(dependencyName);
16811681
}
1682+
boolean preExisting = containsSingleton(dependencyName);
16821683
Object dependencyBean = getBean(dependencyName);
1684+
if (preExisting && dependencyBean instanceof NullBean) {
1685+
// for backwards compatibility with addCandidateEntry in the regular code path
1686+
dependencyBean = null;
1687+
}
16831688
return resolveInstance(dependencyBean, descriptor, type, dependencyName);
16841689
}
16851690
}
@@ -1760,7 +1765,6 @@ private Object resolveInstance(Object candidate, DependencyDescriptor descriptor
17601765
throw new BeanNotOfRequiredTypeException(name, type, candidate.getClass());
17611766
}
17621767
return result;
1763-
17641768
}
17651769

17661770
@Nullable

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

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -960,11 +960,34 @@ void constructorResourceInjectionWithMultipleCandidates() {
960960
@Test
961961
void constructorResourceInjectionWithNoCandidatesAndNoFallback() {
962962
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ConstructorWithoutFallbackBean.class));
963+
963964
assertThatExceptionOfType(UnsatisfiedDependencyException.class)
964965
.isThrownBy(() -> bf.getBean("annotatedBean"))
965966
.satisfies(methodParameterDeclaredOn(ConstructorWithoutFallbackBean.class));
966967
}
967968

969+
@Test
970+
void constructorResourceInjectionWithCandidateAndNoFallback() {
971+
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ConstructorWithoutFallbackBean.class));
972+
RootBeanDefinition tb = new RootBeanDefinition(NullFactoryMethods.class);
973+
tb.setFactoryMethodName("createTestBean");
974+
bf.registerBeanDefinition("testBean", tb);
975+
976+
bf.getBean("testBean");
977+
assertThat(bf.getBean("annotatedBean", ConstructorWithoutFallbackBean.class).getTestBean3()).isNull();
978+
}
979+
980+
@Test
981+
void constructorResourceInjectionWithNameMatchingCandidateAndNoFallback() {
982+
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ConstructorWithoutFallbackBean.class));
983+
RootBeanDefinition tb = new RootBeanDefinition(NullFactoryMethods.class);
984+
tb.setFactoryMethodName("createTestBean");
985+
bf.registerBeanDefinition("testBean3", tb);
986+
987+
bf.getBean("testBean3");
988+
assertThat(bf.getBean("annotatedBean", ConstructorWithoutFallbackBean.class).getTestBean3()).isNull();
989+
}
990+
968991
@Test
969992
void constructorResourceInjectionWithSometimesNullBeanEarly() {
970993
RootBeanDefinition bd = new RootBeanDefinition(ConstructorWithNullableArgument.class);
@@ -1193,6 +1216,7 @@ void singleConstructorInjectionWithEmptyCollectionAsNull() {
11931216
@Test
11941217
void singleConstructorInjectionWithMissingDependency() {
11951218
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(SingleConstructorOptionalCollectionBean.class));
1219+
11961220
assertThatExceptionOfType(UnsatisfiedDependencyException.class)
11971221
.isThrownBy(() -> bf.getBean("annotatedBean"));
11981222
}
@@ -1203,6 +1227,7 @@ void singleConstructorInjectionWithNullDependency() {
12031227
RootBeanDefinition tb = new RootBeanDefinition(NullFactoryMethods.class);
12041228
tb.setFactoryMethodName("createTestBean");
12051229
bf.registerBeanDefinition("testBean", tb);
1230+
12061231
assertThatExceptionOfType(UnsatisfiedDependencyException.class)
12071232
.isThrownBy(() -> bf.getBean("annotatedBean"));
12081233
}
@@ -3060,7 +3085,6 @@ public static class ConstructorWithoutFallbackBean {
30603085

30613086
protected ITestBean testBean3;
30623087

3063-
@Autowired(required = false)
30643088
public ConstructorWithoutFallbackBean(ITestBean testBean3) {
30653089
this.testBean3 = testBean3;
30663090
}
@@ -3075,7 +3099,6 @@ public static class ConstructorWithNullableArgument {
30753099

30763100
protected ITestBean testBean3;
30773101

3078-
@Autowired(required = false)
30793102
public ConstructorWithNullableArgument(@Nullable ITestBean testBean3) {
30803103
this.testBean3 = testBean3;
30813104
}

0 commit comments

Comments
 (0)