From 7e74fd2b7fb30e6206d40bb7235d82433682386a Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 22 Jan 2013 17:53:30 -0800 Subject: [PATCH] Consider primary attribute with getBean(Class) Update DefaultListableBeanFactory.getBean(Class beanClass) to consider the 'primary' attribute of bean definitions. This makes getBean() behave in the same way as autowiring. Issue: SPR-7854 --- .../support/DefaultListableBeanFactory.java | 15 +++++++++ .../DefaultListableBeanFactoryTests.java | 33 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 432663ab79..23512f9e23 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -90,6 +90,7 @@ import org.springframework.util.StringUtils; * @author Sam Brannen * @author Costin Leau * @author Chris Beams + * @author Phillip Webb * @since 16 April 2001 * @see StaticListableBeanFactory * @see PropertiesBeanDefinitionReader @@ -272,6 +273,20 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto return getBean(beanNames[0], requiredType); } else if (beanNames.length > 1) { + T primaryBean = null; + for (String beanName : beanNames) { + T beanInstance = getBean(beanName, requiredType); + if (isPrimary(beanName, beanInstance)) { + if(primaryBean != null) { + throw new NoUniqueBeanDefinitionException(requiredType, beanNames.length, + "more than one 'primary' bean found of required type: " + Arrays.asList(beanNames)); + } + primaryBean = beanInstance; + } + } + if(primaryBean != null) { + return primaryBean; + } throw new NoUniqueBeanDefinitionException(requiredType, beanNames); } else if (getParentBeanFactory() != null) { diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java index e93e95973d..fd134fcc3d 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java @@ -17,6 +17,8 @@ package org.springframework.beans.factory; import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -49,7 +51,9 @@ import javax.security.auth.Subject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Ignore; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.springframework.beans.BeansException; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.NotWritablePropertyException; @@ -102,11 +106,14 @@ import org.springframework.util.StopWatch; * @author Rick Evans * @author Sam Brannen * @author Chris Beams + * @author Phillip Webb */ public class DefaultListableBeanFactoryTests { private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class); + @Rule + public ExpectedException thrown = ExpectedException.none(); @Test public void testUnreferencedSingletonWasInstantiated() { @@ -1285,6 +1292,32 @@ public class DefaultListableBeanFactoryTests { lbf.getBean(TestBean.class); } + @Test + public void testGetBeanByTypeWithPrimary() throws Exception { + DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); + RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class); + RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class); + bd2.setPrimary(true); + lbf.registerBeanDefinition("bd1", bd1); + lbf.registerBeanDefinition("bd2", bd2); + TestBean bean = lbf.getBean(TestBean.class); + assertThat(bean.getBeanName(), equalTo("bd2")); + } + + @Test + public void testGetBeanByTypeWithMultiplePrimary() throws Exception { + DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); + RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class); + bd1.setPrimary(true); + RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class); + bd2.setPrimary(true); + lbf.registerBeanDefinition("bd1", bd1); + lbf.registerBeanDefinition("bd2", bd2); + thrown.expect(NoUniqueBeanDefinitionException.class); + thrown.expectMessage(containsString("more than one 'primary'")); + lbf.getBean(TestBean.class); + } + @Test public void testGetBeanByTypeFiltersOutNonAutowireCandidates() { DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();