DefaultListableBeanFactory only calls getPriority for non-null instance

Issue: SPR-16508
This commit is contained in:
Juergen Hoeller 2018-02-16 17:27:42 +01:00
parent 6920a1f958
commit c9d08bff41
2 changed files with 67 additions and 34 deletions

View File

@ -1006,7 +1006,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
} }
} }
if (!autowireCandidates.isEmpty()) { if (!autowireCandidates.isEmpty()) {
candidateNames = autowireCandidates.toArray(new String[autowireCandidates.size()]); candidateNames = StringUtils.toStringArray(autowireCandidates);
} }
} }
@ -1017,8 +1017,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
else if (candidateNames.length > 1) { else if (candidateNames.length > 1) {
Map<String, Object> candidates = new LinkedHashMap<>(candidateNames.length); Map<String, Object> candidates = new LinkedHashMap<>(candidateNames.length);
for (String beanName : candidateNames) { for (String beanName : candidateNames) {
if (containsSingleton(beanName)) { if (containsSingleton(beanName) && args == null) {
candidates.put(beanName, getBean(beanName, requiredType, args)); Object beanInstance = getBean(beanName);
candidates.put(beanName, (beanInstance instanceof NullBean ? null : beanInstance));
} }
else { else {
candidates.put(beanName, getType(beanName)); candidates.put(beanName, getType(beanName));
@ -1030,7 +1031,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
} }
if (candidateName != null) { if (candidateName != null) {
Object beanInstance = candidates.get(candidateName); Object beanInstance = candidates.get(candidateName);
if (beanInstance instanceof Class) { if (beanInstance == null || beanInstance instanceof Class) {
beanInstance = getBean(candidateName, requiredType, args); beanInstance = getBean(candidateName, requiredType, args);
} }
return new NamedBeanHolder<>(candidateName, (T) beanInstance); return new NamedBeanHolder<>(candidateName, (T) beanInstance);
@ -1413,6 +1414,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
for (Map.Entry<String, Object> entry : candidates.entrySet()) { for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey(); String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue(); Object beanInstance = entry.getValue();
if (beanInstance != null) {
Integer candidatePriority = getPriority(beanInstance); Integer candidatePriority = getPriority(beanInstance);
if (candidatePriority != null) { if (candidatePriority != null) {
if (highestPriorityBeanName != null) { if (highestPriorityBeanName != null) {
@ -1432,6 +1434,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
} }
} }
} }
}
return highestPriorityBeanName; return highestPriorityBeanName;
} }

View File

@ -1434,7 +1434,7 @@ public class DefaultListableBeanFactoryTests {
} }
@Test @Test
public void testGetBeanByTypeWithPrimary() throws Exception { public void testGetBeanByTypeWithPrimary() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class); RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
bd1.setLazyInit(true); bd1.setLazyInit(true);
@ -1448,7 +1448,7 @@ public class DefaultListableBeanFactoryTests {
} }
@Test @Test
public void testGetBeanByTypeWithMultiplePrimary() throws Exception { public void testGetBeanByTypeWithMultiplePrimary() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class); RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
bd1.setPrimary(true); bd1.setPrimary(true);
@ -1462,19 +1462,39 @@ public class DefaultListableBeanFactoryTests {
} }
@Test @Test
public void testGetBeanByTypeWithPriority() throws Exception { public void testGetBeanByTypeWithPriority() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class); RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class); RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class);
RootBeanDefinition bd3 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
lbf.registerBeanDefinition("bd1", bd1); lbf.registerBeanDefinition("bd1", bd1);
lbf.registerBeanDefinition("bd2", bd2); lbf.registerBeanDefinition("bd2", bd2);
lbf.registerBeanDefinition("bd3", bd3);
lbf.preInstantiateSingletons();
TestBean bean = lbf.getBean(TestBean.class); TestBean bean = lbf.getBean(TestBean.class);
assertThat(bean.getBeanName(), equalTo("bd1")); assertThat(bean.getBeanName(), equalTo("bd1"));
} }
@Test @Test
public void testGetBeanByTypeWithMultiplePriority() throws Exception { public void testMapInjectionWithPriority() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class);
RootBeanDefinition bd3 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
RootBeanDefinition bd4 = new RootBeanDefinition(TestBeanRecipient.class, RootBeanDefinition.AUTOWIRE_CONSTRUCTOR, false);
lbf.registerBeanDefinition("bd1", bd1);
lbf.registerBeanDefinition("bd2", bd2);
lbf.registerBeanDefinition("bd3", bd3);
lbf.registerBeanDefinition("bd4", bd4);
lbf.preInstantiateSingletons();
TestBean bean = lbf.getBean(TestBeanRecipient.class).testBean;
assertThat(bean.getBeanName(), equalTo("bd1"));
}
@Test
public void testGetBeanByTypeWithMultiplePriority() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class); RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
@ -1488,7 +1508,7 @@ public class DefaultListableBeanFactoryTests {
} }
@Test @Test
public void testGetBeanByTypeWithPriorityAndNullInstance() throws Exception { public void testGetBeanByTypeWithPriorityAndNullInstance() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class); RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
@ -1500,7 +1520,7 @@ public class DefaultListableBeanFactoryTests {
} }
@Test @Test
public void testGetBeanByTypePrimaryHasPrecedenceOverPriority() throws Exception { public void testGetBeanByTypePrimaryHasPrecedenceOverPriority() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class); RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
@ -2278,7 +2298,7 @@ public class DefaultListableBeanFactoryTests {
/** /**
* @Test * @Test
* public void testPrototypeCreationIsFastEnough2() throws Exception { * public void testPrototypeCreationIsFastEnough2() {
* if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) { * if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) {
* // Skip this test: Trace logging blows the time limit. * // Skip this test: Trace logging blows the time limit.
* return; * return;
@ -2576,7 +2596,7 @@ public class DefaultListableBeanFactoryTests {
} }
@Test(expected = IllegalStateException.class) @Test(expected = IllegalStateException.class)
public void testScopingBeanToUnregisteredScopeResultsInAnException() throws Exception { public void testScopingBeanToUnregisteredScopeResultsInAnException() {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class); BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition(); AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
beanDefinition.setScope("he put himself so low could hardly look me in the face"); beanDefinition.setScope("he put himself so low could hardly look me in the face");
@ -2587,7 +2607,7 @@ public class DefaultListableBeanFactoryTests {
} }
@Test @Test
public void testExplicitScopeInheritanceForChildBeanDefinitions() throws Exception { public void testExplicitScopeInheritanceForChildBeanDefinitions() {
String theChildScope = "bonanza!"; String theChildScope = "bonanza!";
RootBeanDefinition parent = new RootBeanDefinition(); RootBeanDefinition parent = new RootBeanDefinition();
@ -2606,7 +2626,7 @@ public class DefaultListableBeanFactoryTests {
} }
@Test @Test
public void testScopeInheritanceForChildBeanDefinitions() throws Exception { public void testScopeInheritanceForChildBeanDefinitions() {
RootBeanDefinition parent = new RootBeanDefinition(); RootBeanDefinition parent = new RootBeanDefinition();
parent.setScope("bonanza!"); parent.setScope("bonanza!");
@ -2993,7 +3013,7 @@ public class DefaultListableBeanFactoryTests {
} }
@Override @Override
public T call() throws Exception { public T call() {
throw new IllegalStateException(); throw new IllegalStateException();
} }
} }
@ -3004,7 +3024,7 @@ public class DefaultListableBeanFactoryTests {
public boolean initialized = false; public boolean initialized = false;
@Override @Override
public Object getObject() throws Exception { public Object getObject() {
this.initialized = true; this.initialized = true;
return ""; return "";
} }
@ -3026,7 +3046,7 @@ public class DefaultListableBeanFactoryTests {
public boolean initialized = false; public boolean initialized = false;
@Override @Override
public Object getObject() throws Exception { public Object getObject() {
this.initialized = true; this.initialized = true;
return ""; return "";
} }
@ -3258,7 +3278,7 @@ public class DefaultListableBeanFactoryTests {
private static class NullTestBeanFactoryBean<T> implements FactoryBean<TestBean> { private static class NullTestBeanFactoryBean<T> implements FactoryBean<TestBean> {
@Override @Override
public TestBean getObject() throws Exception { public TestBean getObject() {
return null; return null;
} }
@ -3274,6 +3294,16 @@ public class DefaultListableBeanFactoryTests {
} }
private static class TestBeanRecipient {
public TestBean testBean;
public TestBeanRecipient(TestBean testBean) {
this.testBean = testBean;
}
}
enum NonPublicEnum { enum NonPublicEnum {
VALUE_1, VALUE_2; VALUE_1, VALUE_2;