diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/BeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/BeanFactory.java index 6d641e9a26e..5a7493909b2 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/BeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/BeanFactory.java @@ -149,6 +149,15 @@ public interface BeanFactory { */ T getBean(String name, Class requiredType) throws BeansException; + /** + * Return the bean instance that uniquely matches the given object type, if any. + * @param requiredType type the bean must match; can be an interface or superclass. + * {@literal null} is disallowed. + * @return bean matching required type + * @throws NoSuchBeanDefinitionException if there is not exactly one matching bean found + */ + T getBean(Class requiredType) throws BeansException; + /** * Return an instance, which may be shared or independent, of the specified bean. *

Allows for specifying explicit constructor arguments / factory method arguments, diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 3966d79b795..18609d8858b 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -242,6 +242,19 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto // Implementation of ListableBeanFactory interface //--------------------------------------------------------------------- + public T getBean(Class requiredType) throws BeansException { + String[] beanNames = getBeanNamesForType(requiredType); + if (beanNames.length == 1) { + return getBean(beanNames[0], requiredType); + } + else if (beanNames.length == 0 && getParentBeanFactory() != null) { + return getParentBeanFactory().getBean(requiredType); + } + else { + throw new NoSuchBeanDefinitionException(requiredType, "expected single bean but found " + beanNames.length); + } + } + @Override public boolean containsBeanDefinition(String beanName) { return this.beanDefinitionMap.containsKey(beanName); diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java index 864c0f81e82..271356b0706 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java @@ -112,6 +112,16 @@ public class StaticListableBeanFactory implements ListableBeanFactory { return (T) bean; } + public T getBean(Class requiredType) throws BeansException { + String[] beanNames = getBeanNamesForType(requiredType); + if (beanNames.length == 1) { + return getBean(beanNames[0], requiredType); + } + else { + throw new NoSuchBeanDefinitionException(requiredType, "expected single bean but found " + beanNames.length); + } + } + public Object getBean(String name, Object... args) throws BeansException { if (args != null) { throw new UnsupportedOperationException( diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/AbstractBeanFactoryTests.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/AbstractBeanFactoryTests.java index ce8e664be4d..eba0541e09d 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/AbstractBeanFactoryTests.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/AbstractBeanFactoryTests.java @@ -64,7 +64,7 @@ public abstract class AbstractBeanFactoryTests extends TestCase { public void testGetBeanWithNullArg() { try { - getBeanFactory().getBean(null); + getBeanFactory().getBean((String) null); fail("Can't get null bean"); } catch (IllegalArgumentException ex) { diff --git a/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index 2114820abbb..2dd86e26d93 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -892,6 +892,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader return getBeanFactory().getBean(name, requiredType); } + public T getBean(Class requiredType) throws BeansException { + return getBeanFactory().getBean(requiredType); + } + public Object getBean(String name, Object... args) throws BeansException { return getBeanFactory().getBean(name, args); } diff --git a/org.springframework.context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java b/org.springframework.context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java index cddc2b043a7..493dc7618b3 100644 --- a/org.springframework.context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java +++ b/org.springframework.context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java @@ -118,6 +118,10 @@ public class SimpleJndiBeanFactory extends JndiLocatorSupport implements BeanFac } } + public T getBean(Class requiredType) throws BeansException { + return getBean(requiredType.getSimpleName(), requiredType); + } + public Object getBean(String name, Object... args) throws BeansException { if (args != null) { throw new UnsupportedOperationException( diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/jsr330/SpringAtInjectTck.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/jsr330/SpringAtInjectTck.java index bfad584d1c6..821b0465abb 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation/jsr330/SpringAtInjectTck.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation/jsr330/SpringAtInjectTck.java @@ -31,10 +31,7 @@ import org.atinject.tck.auto.accessories.SpareTire; import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.AutowireCandidateQualifier; -import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; -import org.springframework.context.annotation.AnnotationConfigUtils; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.ScopeMetadata; import org.springframework.context.annotation.ScopeMetadataResolver; @@ -71,59 +68,9 @@ public class SpringAtInjectTck { bdr.registerBean(FuelTank.class); ac.refresh(); - Car car = ac.getBean("convertible", Car.class); + Car car = ac.getBean(Car.class); return Tck.testsFor(car, false, true); } - public static Test suiteX() { - GenericApplicationContext ac = new GenericApplicationContext(); - - GenericBeanDefinition carDef = new GenericBeanDefinition(); - carDef.setScope(GenericBeanDefinition.SCOPE_PROTOTYPE); - carDef.setBeanClass(Convertible.class); - ac.registerBeanDefinition("car", carDef); - - GenericBeanDefinition driversSeatDef = new GenericBeanDefinition(); - driversSeatDef.setScope(GenericBeanDefinition.SCOPE_PROTOTYPE); - driversSeatDef.setBeanClass(DriversSeat.class); - driversSeatDef.addQualifier(new AutowireCandidateQualifier(Drivers.class)); - ac.registerBeanDefinition("driversSeat", driversSeatDef); - - GenericBeanDefinition seatDef = new GenericBeanDefinition(); - seatDef.setBeanClass(Seat.class); - seatDef.setPrimary(true); - ac.registerBeanDefinition("seat", seatDef); - - GenericBeanDefinition engineDef = new GenericBeanDefinition(); - engineDef.setScope(GenericBeanDefinition.SCOPE_PROTOTYPE); - engineDef.setBeanClass(V8Engine.class); - ac.registerBeanDefinition("engine", engineDef); - - GenericBeanDefinition spareDef = new GenericBeanDefinition(); - spareDef.setScope(GenericBeanDefinition.SCOPE_PROTOTYPE); - spareDef.setBeanClass(SpareTire.class); - spareDef.addQualifier(new AutowireCandidateQualifier(Drivers.class)); - ac.registerBeanDefinition("spare", spareDef); - - GenericBeanDefinition cupholderDef = new GenericBeanDefinition(); - cupholderDef.setBeanClass(Cupholder.class); - ac.registerBeanDefinition("cupholder", cupholderDef); - - GenericBeanDefinition tireDef = new GenericBeanDefinition(); - tireDef.setScope(GenericBeanDefinition.SCOPE_PROTOTYPE); - tireDef.setBeanClass(Tire.class); - tireDef.setPrimary(true); - ac.registerBeanDefinition("tire", tireDef); - - GenericBeanDefinition fuelTankDef = new GenericBeanDefinition(); - fuelTankDef.setBeanClass(FuelTank.class); - ac.registerBeanDefinition("fuelTank", fuelTankDef); - - AnnotationConfigUtils.registerAnnotationConfigProcessors(ac); - ac.refresh(); - Car car = ac.getBean("car", Car.class); - return Tck.testsFor(car, false, true); - } - }