Introduced NoUniqueBeanDefinitionException as a dedicated subclass of NoSuchBeanDefinitionException
Issue: SPR-10194
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -143,7 +143,7 @@ public interface BeanFactory {
|
||||
* is {@code Object.class}, this method will succeed whatever the class of the
|
||||
* returned instance.
|
||||
* @return an instance of the bean
|
||||
* @throws NoSuchBeanDefinitionException if there's no such bean definition
|
||||
* @throws NoSuchBeanDefinitionException if there is no such bean definition
|
||||
* @throws BeanNotOfRequiredTypeException if the bean is not of the required type
|
||||
* @throws BeansException if the bean could not be created
|
||||
*/
|
||||
@@ -158,7 +158,8 @@ public interface BeanFactory {
|
||||
* of the given type. For more extensive retrieval operations across sets of beans,
|
||||
* use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
|
||||
* @return an instance of the single bean matching the required type
|
||||
* @throws NoSuchBeanDefinitionException if there is not exactly one matching bean found
|
||||
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
|
||||
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
|
||||
* @since 3.0
|
||||
* @see ListableBeanFactory
|
||||
*/
|
||||
@@ -172,7 +173,7 @@ public interface BeanFactory {
|
||||
* @param args arguments to use if creating a prototype using explicit arguments to a
|
||||
* static factory method. It is invalid to use a non-null args value in any other case.
|
||||
* @return an instance of the bean
|
||||
* @throws NoSuchBeanDefinitionException if there's no such bean definition
|
||||
* @throws NoSuchBeanDefinitionException if there is no such bean definition
|
||||
* @throws BeanDefinitionStoreException if arguments have been given but
|
||||
* the affected bean isn't a prototype
|
||||
* @throws BeansException if the bean could not be created
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -310,20 +310,15 @@ public abstract class BeanFactoryUtils {
|
||||
* @param lbf the bean factory
|
||||
* @param type type of bean to match
|
||||
* @return the matching bean instance
|
||||
* @throws NoSuchBeanDefinitionException
|
||||
* if 0 or more than 1 beans of the given type were found
|
||||
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
|
||||
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
|
||||
* @throws BeansException if the bean could not be created
|
||||
*/
|
||||
public static <T> T beanOfTypeIncludingAncestors(ListableBeanFactory lbf, Class<T> type)
|
||||
throws BeansException {
|
||||
|
||||
Map<String, T> beansOfType = beansOfTypeIncludingAncestors(lbf, type);
|
||||
if (beansOfType.size() == 1) {
|
||||
return beansOfType.values().iterator().next();
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(type, "expected single bean but found " + beansOfType.size());
|
||||
}
|
||||
return uniqueBean(type, beansOfType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -351,8 +346,8 @@ public abstract class BeanFactoryUtils {
|
||||
* eagerly initialized to determine their type: So be aware that passing in "true"
|
||||
* for this flag will initialize FactoryBeans and "factory-bean" references.
|
||||
* @return the matching bean instance
|
||||
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
|
||||
* if 0 or more than 1 beans of the given type were found
|
||||
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
|
||||
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
|
||||
* @throws BeansException if the bean could not be created
|
||||
*/
|
||||
public static <T> T beanOfTypeIncludingAncestors(
|
||||
@@ -360,12 +355,7 @@ public abstract class BeanFactoryUtils {
|
||||
throws BeansException {
|
||||
|
||||
Map<String, T> beansOfType = beansOfTypeIncludingAncestors(lbf, type, includeNonSingletons, allowEagerInit);
|
||||
if (beansOfType.size() == 1) {
|
||||
return beansOfType.values().iterator().next();
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(type, "expected single bean but found " + beansOfType.size());
|
||||
}
|
||||
return uniqueBean(type, beansOfType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -380,19 +370,14 @@ public abstract class BeanFactoryUtils {
|
||||
* @param lbf the bean factory
|
||||
* @param type type of bean to match
|
||||
* @return the matching bean instance
|
||||
* @throws NoSuchBeanDefinitionException
|
||||
* if 0 or more than 1 beans of the given type were found
|
||||
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
|
||||
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
|
||||
* @throws BeansException if the bean could not be created
|
||||
*/
|
||||
public static <T> T beanOfType(ListableBeanFactory lbf, Class<T> type) throws BeansException {
|
||||
Assert.notNull(lbf, "ListableBeanFactory must not be null");
|
||||
Map<String, T> beansOfType = lbf.getBeansOfType(type);
|
||||
if (beansOfType.size() == 1) {
|
||||
return beansOfType.values().iterator().next();
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(type, "expected single bean but found " + beansOfType.size());
|
||||
}
|
||||
return uniqueBean(type, beansOfType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -415,8 +400,8 @@ public abstract class BeanFactoryUtils {
|
||||
* eagerly initialized to determine their type: So be aware that passing in "true"
|
||||
* for this flag will initialize FactoryBeans and "factory-bean" references.
|
||||
* @return the matching bean instance
|
||||
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
|
||||
* if 0 or more than 1 beans of the given type were found
|
||||
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
|
||||
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
|
||||
* @throws BeansException if the bean could not be created
|
||||
*/
|
||||
public static <T> T beanOfType(
|
||||
@@ -425,11 +410,27 @@ public abstract class BeanFactoryUtils {
|
||||
|
||||
Assert.notNull(lbf, "ListableBeanFactory must not be null");
|
||||
Map<String, T> beansOfType = lbf.getBeansOfType(type, includeNonSingletons, allowEagerInit);
|
||||
if (beansOfType.size() == 1) {
|
||||
return beansOfType.values().iterator().next();
|
||||
return uniqueBean(type, beansOfType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a unique bean for the given type from the given Map of matching beans.
|
||||
* @param type type of bean to match
|
||||
* @param matchingBeans all matching beans found
|
||||
* @return the unique bean instance
|
||||
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
|
||||
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
|
||||
*/
|
||||
private static <T> T uniqueBean(Class<T> type, Map<String, T> matchingBeans) {
|
||||
int nrFound = matchingBeans.size();
|
||||
if (nrFound == 1) {
|
||||
return matchingBeans.values().iterator().next();
|
||||
}
|
||||
else if (nrFound > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(type, "expected single bean but found " + beansOfType.size());
|
||||
throw new NoSuchBeanDefinitionException(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,11 +20,13 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Exception thrown when a {@code BeanFactory} is asked for a bean
|
||||
* instance for which it cannot find a definition.
|
||||
* Exception thrown when a {@code BeanFactory} is asked for a bean instance
|
||||
* for which it cannot find a definition.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @see BeanFactory#getBean(String)
|
||||
* @see BeanFactory#getBean(Class)
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class NoSuchBeanDefinitionException extends BeansException {
|
||||
@@ -60,7 +62,7 @@ public class NoSuchBeanDefinitionException extends BeansException {
|
||||
* @param type required type of the missing bean
|
||||
*/
|
||||
public NoSuchBeanDefinitionException(Class<?> type) {
|
||||
super("No unique bean of type [" + type.getName() + "] is defined");
|
||||
super("No qualifying bean of type [" + type.getName() + "] is defined");
|
||||
this.beanType = type;
|
||||
}
|
||||
|
||||
@@ -70,7 +72,7 @@ public class NoSuchBeanDefinitionException extends BeansException {
|
||||
* @param message detailed message describing the problem
|
||||
*/
|
||||
public NoSuchBeanDefinitionException(Class<?> type, String message) {
|
||||
super("No unique bean of type [" + type.getName() + "] is defined: " + message);
|
||||
super("No qualifying bean of type [" + type.getName() + "] is defined: " + message);
|
||||
this.beanType = type;
|
||||
}
|
||||
|
||||
@@ -81,7 +83,7 @@ public class NoSuchBeanDefinitionException extends BeansException {
|
||||
* @param message detailed message describing the problem
|
||||
*/
|
||||
public NoSuchBeanDefinitionException(Class<?> type, String dependencyDescription, String message) {
|
||||
super("No matching bean of type [" + type.getName() + "] found for dependency" +
|
||||
super("No qualifying bean of type [" + type.getName() + "] found for dependency" +
|
||||
(StringUtils.hasLength(dependencyDescription) ? " [" + dependencyDescription + "]" : "") +
|
||||
": " + message);
|
||||
this.beanType = type;
|
||||
@@ -89,19 +91,26 @@ public class NoSuchBeanDefinitionException extends BeansException {
|
||||
|
||||
|
||||
/**
|
||||
* Return the name of the missing bean, if it was a lookup <em>by name</em>
|
||||
* that failed.
|
||||
* Return the name of the missing bean, if it was a lookup <em>by name</em> that failed.
|
||||
*/
|
||||
public String getBeanName() {
|
||||
return this.beanName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the required type of the missing bean, if it was a lookup
|
||||
* <em>by type</em> that failed.
|
||||
* Return the required type of the missing bean, if it was a lookup <em>by type</em> that failed.
|
||||
*/
|
||||
public Class<?> getBeanType() {
|
||||
return this.beanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of beans found when only one matching bean was expected.
|
||||
* For a regular NoSuchBeanDefinitionException, this will always be 0.
|
||||
* @see NoUniqueBeanDefinitionException
|
||||
*/
|
||||
public int getNumberOfBeansFound() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Exception thrown when a {@code BeanFactory} is asked for a bean instance for which
|
||||
* multiple matching candidates have been found when only one matching bean was expected.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.2.1
|
||||
* @see BeanFactory#getBean(Class)
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class NoUniqueBeanDefinitionException extends NoSuchBeanDefinitionException {
|
||||
|
||||
private int numberOfBeansFound;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code NoUniqueBeanDefinitionException}.
|
||||
* @param type required type of the non-unique bean
|
||||
* @param numberOfBeansFound the number of matching beans
|
||||
* @param message detailed message describing the problem
|
||||
*/
|
||||
public NoUniqueBeanDefinitionException(Class<?> type, int numberOfBeansFound, String message) {
|
||||
super(type, message);
|
||||
this.numberOfBeansFound = numberOfBeansFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code NoUniqueBeanDefinitionException}.
|
||||
* @param type required type of the non-unique bean
|
||||
* @param beanNamesFound the names of all matching beans (as a Collection)
|
||||
*/
|
||||
public NoUniqueBeanDefinitionException(Class<?> type, Collection<String> beanNamesFound) {
|
||||
this(type, beanNamesFound.size(), "expected single matching bean but found " + beanNamesFound.size() + ": " +
|
||||
StringUtils.collectionToCommaDelimitedString(beanNamesFound));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code NoUniqueBeanDefinitionException}.
|
||||
* @param type required type of the non-unique bean
|
||||
* @param beanNamesFound the names of all matching beans (as an array)
|
||||
*/
|
||||
public NoUniqueBeanDefinitionException(Class<?> type, String... beanNamesFound) {
|
||||
this(type, Arrays.asList(beanNamesFound));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the number of beans found when only one matching bean was expected.
|
||||
* For a NoUniqueBeanDefinitionException, this will usually be higher than 1.
|
||||
* @see #getBeanType()
|
||||
*/
|
||||
@Override
|
||||
public int getNumberOfBeansFound() {
|
||||
return this.numberOfBeansFound;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,6 +50,7 @@ import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.CannotLoadBeanClassException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.SmartFactoryBean;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
@@ -270,12 +271,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (beanNames.length == 1) {
|
||||
return getBean(beanNames[0], requiredType);
|
||||
}
|
||||
else if (beanNames.length == 0 && getParentBeanFactory() != null) {
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else if (getParentBeanFactory() != null) {
|
||||
return getParentBeanFactory().getBean(requiredType);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(requiredType, "expected single bean but found " +
|
||||
beanNames.length + ": " + StringUtils.arrayToCommaDelimitedString(beanNames));
|
||||
throw new NoSuchBeanDefinitionException(requiredType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,8 +826,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
if (matchingBeans.size() > 1) {
|
||||
String primaryBeanName = determinePrimaryCandidate(matchingBeans, descriptor);
|
||||
if (primaryBeanName == null) {
|
||||
throw new NoSuchBeanDefinitionException(type, "expected single matching bean but found " +
|
||||
matchingBeans.size() + ": " + matchingBeans.keySet());
|
||||
throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
|
||||
}
|
||||
if (autowiredBeanNames != null) {
|
||||
autowiredBeanNames.add(primaryBeanName);
|
||||
@@ -895,7 +897,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
boolean candidateLocal = containsBeanDefinition(candidateBeanName);
|
||||
boolean primaryLocal = containsBeanDefinition(primaryBeanName);
|
||||
if (candidateLocal == primaryLocal) {
|
||||
throw new NoSuchBeanDefinitionException(descriptor.getDependencyType(),
|
||||
throw new NoUniqueBeanDefinitionException(descriptor.getDependencyType(), candidateBeans.size(),
|
||||
"more than one 'primary' bean found among candidates: " + candidateBeans.keySet());
|
||||
}
|
||||
else if (candidateLocal && !primaryLocal) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,6 +31,7 @@ import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||
import org.springframework.beans.factory.SmartFactoryBean;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -117,8 +118,11 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
||||
if (beanNames.length == 1) {
|
||||
return getBean(beanNames[0], requiredType);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(requiredType, "expected single bean but found " + beanNames.length);
|
||||
throw new NoSuchBeanDefinitionException(requiredType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user