Skip to content

Commit c9d08bf

Browse files
committed
DefaultListableBeanFactory only calls getPriority for non-null instance
Issue: SPR-16508
1 parent 6920a1f commit c9d08bf

File tree

2 files changed

+67
-34
lines changed

2 files changed

+67
-34
lines changed

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

+19-16
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,7 @@ private <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType, @Nullable
10061006
}
10071007
}
10081008
if (!autowireCandidates.isEmpty()) {
1009-
candidateNames = autowireCandidates.toArray(new String[autowireCandidates.size()]);
1009+
candidateNames = StringUtils.toStringArray(autowireCandidates);
10101010
}
10111011
}
10121012

@@ -1017,8 +1017,9 @@ private <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType, @Nullable
10171017
else if (candidateNames.length > 1) {
10181018
Map<String, Object> candidates = new LinkedHashMap<>(candidateNames.length);
10191019
for (String beanName : candidateNames) {
1020-
if (containsSingleton(beanName)) {
1021-
candidates.put(beanName, getBean(beanName, requiredType, args));
1020+
if (containsSingleton(beanName) && args == null) {
1021+
Object beanInstance = getBean(beanName);
1022+
candidates.put(beanName, (beanInstance instanceof NullBean ? null : beanInstance));
10221023
}
10231024
else {
10241025
candidates.put(beanName, getType(beanName));
@@ -1030,7 +1031,7 @@ else if (candidateNames.length > 1) {
10301031
}
10311032
if (candidateName != null) {
10321033
Object beanInstance = candidates.get(candidateName);
1033-
if (beanInstance instanceof Class) {
1034+
if (beanInstance == null || beanInstance instanceof Class) {
10341035
beanInstance = getBean(candidateName, requiredType, args);
10351036
}
10361037
return new NamedBeanHolder<>(candidateName, (T) beanInstance);
@@ -1413,23 +1414,25 @@ protected String determineHighestPriorityCandidate(Map<String, Object> candidate
14131414
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
14141415
String candidateBeanName = entry.getKey();
14151416
Object beanInstance = entry.getValue();
1416-
Integer candidatePriority = getPriority(beanInstance);
1417-
if (candidatePriority != null) {
1418-
if (highestPriorityBeanName != null) {
1419-
if (candidatePriority.equals(highestPriority)) {
1420-
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
1421-
"Multiple beans found with the same priority ('" + highestPriority +
1422-
"') among candidates: " + candidates.keySet());
1417+
if (beanInstance != null) {
1418+
Integer candidatePriority = getPriority(beanInstance);
1419+
if (candidatePriority != null) {
1420+
if (highestPriorityBeanName != null) {
1421+
if (candidatePriority.equals(highestPriority)) {
1422+
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
1423+
"Multiple beans found with the same priority ('" + highestPriority +
1424+
"') among candidates: " + candidates.keySet());
1425+
}
1426+
else if (candidatePriority < highestPriority) {
1427+
highestPriorityBeanName = candidateBeanName;
1428+
highestPriority = candidatePriority;
1429+
}
14231430
}
1424-
else if (candidatePriority < highestPriority) {
1431+
else {
14251432
highestPriorityBeanName = candidateBeanName;
14261433
highestPriority = candidatePriority;
14271434
}
14281435
}
1429-
else {
1430-
highestPriorityBeanName = candidateBeanName;
1431-
highestPriority = candidatePriority;
1432-
}
14331436
}
14341437
}
14351438
return highestPriorityBeanName;

spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

+48-18
Original file line numberDiff line numberDiff line change
@@ -1434,7 +1434,7 @@ public void testGetBeanByTypeWithAmbiguity() {
14341434
}
14351435

14361436
@Test
1437-
public void testGetBeanByTypeWithPrimary() throws Exception {
1437+
public void testGetBeanByTypeWithPrimary() {
14381438
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
14391439
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
14401440
bd1.setLazyInit(true);
@@ -1448,7 +1448,7 @@ public void testGetBeanByTypeWithPrimary() throws Exception {
14481448
}
14491449

14501450
@Test
1451-
public void testGetBeanByTypeWithMultiplePrimary() throws Exception {
1451+
public void testGetBeanByTypeWithMultiplePrimary() {
14521452
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
14531453
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
14541454
bd1.setPrimary(true);
@@ -1462,19 +1462,39 @@ public void testGetBeanByTypeWithMultiplePrimary() throws Exception {
14621462
}
14631463

14641464
@Test
1465-
public void testGetBeanByTypeWithPriority() throws Exception {
1465+
public void testGetBeanByTypeWithPriority() {
14661466
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
14671467
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
14681468
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
14691469
RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class);
1470+
RootBeanDefinition bd3 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
14701471
lbf.registerBeanDefinition("bd1", bd1);
14711472
lbf.registerBeanDefinition("bd2", bd2);
1473+
lbf.registerBeanDefinition("bd3", bd3);
1474+
lbf.preInstantiateSingletons();
14721475
TestBean bean = lbf.getBean(TestBean.class);
14731476
assertThat(bean.getBeanName(), equalTo("bd1"));
14741477
}
14751478

14761479
@Test
1477-
public void testGetBeanByTypeWithMultiplePriority() throws Exception {
1480+
public void testMapInjectionWithPriority() {
1481+
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
1482+
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
1483+
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
1484+
RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class);
1485+
RootBeanDefinition bd3 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
1486+
RootBeanDefinition bd4 = new RootBeanDefinition(TestBeanRecipient.class, RootBeanDefinition.AUTOWIRE_CONSTRUCTOR, false);
1487+
lbf.registerBeanDefinition("bd1", bd1);
1488+
lbf.registerBeanDefinition("bd2", bd2);
1489+
lbf.registerBeanDefinition("bd3", bd3);
1490+
lbf.registerBeanDefinition("bd4", bd4);
1491+
lbf.preInstantiateSingletons();
1492+
TestBean bean = lbf.getBean(TestBeanRecipient.class).testBean;
1493+
assertThat(bean.getBeanName(), equalTo("bd1"));
1494+
}
1495+
1496+
@Test
1497+
public void testGetBeanByTypeWithMultiplePriority() {
14781498
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
14791499
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
14801500
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
@@ -1483,12 +1503,12 @@ public void testGetBeanByTypeWithMultiplePriority() throws Exception {
14831503
lbf.registerBeanDefinition("bd2", bd2);
14841504
thrown.expect(NoUniqueBeanDefinitionException.class);
14851505
thrown.expectMessage(containsString("Multiple beans found with the same priority"));
1486-
thrown.expectMessage(containsString("5")); // conflicting priority
1506+
thrown.expectMessage(containsString("5")); // conflicting priority
14871507
lbf.getBean(TestBean.class);
14881508
}
14891509

14901510
@Test
1491-
public void testGetBeanByTypeWithPriorityAndNullInstance() throws Exception {
1511+
public void testGetBeanByTypeWithPriorityAndNullInstance() {
14921512
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
14931513
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
14941514
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
@@ -1500,7 +1520,7 @@ public void testGetBeanByTypeWithPriorityAndNullInstance() throws Exception {
15001520
}
15011521

15021522
@Test
1503-
public void testGetBeanByTypePrimaryHasPrecedenceOverPriority() throws Exception {
1523+
public void testGetBeanByTypePrimaryHasPrecedenceOverPriority() {
15041524
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
15051525
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
15061526
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
@@ -1522,7 +1542,7 @@ public void testGetBeanByTypeFiltersOutNonAutowireCandidates() {
15221542

15231543
lbf.registerBeanDefinition("bd1", bd1);
15241544
lbf.registerBeanDefinition("na1", na1);
1525-
TestBean actual = lbf.getBean(TestBean.class); // na1 was filtered
1545+
TestBean actual = lbf.getBean(TestBean.class); // na1 was filtered
15261546
assertSame(lbf.getBean("bd1", TestBean.class), actual);
15271547

15281548
lbf.registerBeanDefinition("bd2", bd2);
@@ -1605,7 +1625,7 @@ public void testGetBeanByTypeInstanceFiltersOutNonAutowireCandidates() {
16051625

16061626
lbf.registerBeanDefinition("bd1", bd1);
16071627
lbf.registerBeanDefinition("na1", na1);
1608-
ConstructorDependency actual = lbf.getBean(ConstructorDependency.class, 42); // na1 was filtered
1628+
ConstructorDependency actual = lbf.getBean(ConstructorDependency.class, 42); // na1 was filtered
16091629
assertThat(actual.beanName, equalTo("bd1"));
16101630

16111631
lbf.registerBeanDefinition("bd2", bd2);
@@ -1850,7 +1870,7 @@ public void testAutowireBeanByTypeWithIdenticalPriorityCandidates() {
18501870
// expected
18511871
assertNotNull("Exception should have cause", ex.getCause());
18521872
assertEquals("Wrong cause type", NoUniqueBeanDefinitionException.class, ex.getCause().getClass());
1853-
assertTrue(ex.getMessage().contains("5")); // conflicting priority
1873+
assertTrue(ex.getMessage().contains("5")); // conflicting priority
18541874
}
18551875
}
18561876

@@ -2278,7 +2298,7 @@ public void testPrototypeCreationWithDependencyCheckIsFastEnough() {
22782298

22792299
/**
22802300
* @Test
2281-
* public void testPrototypeCreationIsFastEnough2() throws Exception {
2301+
* public void testPrototypeCreationIsFastEnough2() {
22822302
* if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) {
22832303
* // Skip this test: Trace logging blows the time limit.
22842304
* return;
@@ -2576,7 +2596,7 @@ private void findTypeOfPrototypeFactoryMethodOnBeanInstance(boolean singleton) {
25762596
}
25772597

25782598
@Test(expected = IllegalStateException.class)
2579-
public void testScopingBeanToUnregisteredScopeResultsInAnException() throws Exception {
2599+
public void testScopingBeanToUnregisteredScopeResultsInAnException() {
25802600
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class);
25812601
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
25822602
beanDefinition.setScope("he put himself so low could hardly look me in the face");
@@ -2587,7 +2607,7 @@ public void testScopingBeanToUnregisteredScopeResultsInAnException() throws Exce
25872607
}
25882608

25892609
@Test
2590-
public void testExplicitScopeInheritanceForChildBeanDefinitions() throws Exception {
2610+
public void testExplicitScopeInheritanceForChildBeanDefinitions() {
25912611
String theChildScope = "bonanza!";
25922612

25932613
RootBeanDefinition parent = new RootBeanDefinition();
@@ -2606,7 +2626,7 @@ public void testExplicitScopeInheritanceForChildBeanDefinitions() throws Excepti
26062626
}
26072627

26082628
@Test
2609-
public void testScopeInheritanceForChildBeanDefinitions() throws Exception {
2629+
public void testScopeInheritanceForChildBeanDefinitions() {
26102630
RootBeanDefinition parent = new RootBeanDefinition();
26112631
parent.setScope("bonanza!");
26122632

@@ -2993,7 +3013,7 @@ public void run() {
29933013
}
29943014

29953015
@Override
2996-
public T call() throws Exception {
3016+
public T call() {
29973017
throw new IllegalStateException();
29983018
}
29993019
}
@@ -3004,7 +3024,7 @@ public static class LazyInitFactory implements FactoryBean<Object> {
30043024
public boolean initialized = false;
30053025

30063026
@Override
3007-
public Object getObject() throws Exception {
3027+
public Object getObject() {
30083028
this.initialized = true;
30093029
return "";
30103030
}
@@ -3026,7 +3046,7 @@ public static class EagerInitFactory implements SmartFactoryBean<Object> {
30263046
public boolean initialized = false;
30273047

30283048
@Override
3029-
public Object getObject() throws Exception {
3049+
public Object getObject() {
30303050
this.initialized = true;
30313051
return "";
30323052
}
@@ -3258,7 +3278,7 @@ private static class LowPriorityTestBean extends TestBean {
32583278
private static class NullTestBeanFactoryBean<T> implements FactoryBean<TestBean> {
32593279

32603280
@Override
3261-
public TestBean getObject() throws Exception {
3281+
public TestBean getObject() {
32623282
return null;
32633283
}
32643284

@@ -3274,6 +3294,16 @@ public boolean isSingleton() {
32743294
}
32753295

32763296

3297+
private static class TestBeanRecipient {
3298+
3299+
public TestBean testBean;
3300+
3301+
public TestBeanRecipient(TestBean testBean) {
3302+
this.testBean = testBean;
3303+
}
3304+
}
3305+
3306+
32773307
enum NonPublicEnum {
32783308

32793309
VALUE_1, VALUE_2;

0 commit comments

Comments
 (0)