diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/NoSuchBeanDefinitionException.java b/spring-beans/src/main/java/org/springframework/beans/factory/NoSuchBeanDefinitionException.java index 1f3f8d3628..7e41471417 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/NoSuchBeanDefinitionException.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/NoSuchBeanDefinitionException.java @@ -17,6 +17,7 @@ package org.springframework.beans.factory; import org.springframework.beans.BeansException; +import org.springframework.core.ResolvableType; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; @@ -27,6 +28,7 @@ import org.springframework.util.StringUtils; * * @author Rod Johnson * @author Juergen Hoeller + * @author Stephane Nicoll * @see BeanFactory#getBean(String) * @see BeanFactory#getBean(Class) * @see NoUniqueBeanDefinitionException @@ -38,7 +40,7 @@ public class NoSuchBeanDefinitionException extends BeansException { private String beanName; /** Required type of the missing bean */ - private Class beanType; + private ResolvableType beanResolvableType; /** @@ -66,7 +68,7 @@ public class NoSuchBeanDefinitionException extends BeansException { */ public NoSuchBeanDefinitionException(Class type) { super("No qualifying bean of type [" + type.getName() + "] is defined"); - this.beanType = type; + this.beanResolvableType = ResolvableType.forClass(type); } /** @@ -76,7 +78,7 @@ public class NoSuchBeanDefinitionException extends BeansException { */ public NoSuchBeanDefinitionException(Class type, String message) { super("No qualifying bean of type [" + ClassUtils.getQualifiedName(type) + "] is defined: " + message); - this.beanType = type; + this.beanResolvableType = ResolvableType.forClass(type); } /** @@ -84,13 +86,34 @@ public class NoSuchBeanDefinitionException extends BeansException { * @param type required type of the missing bean * @param dependencyDescription a description of the originating dependency * @param message detailed message describing the problem + * @deprecated as of Spring 5.0, in favor of {@link #NoSuchBeanDefinitionException(ResolvableType, String)} */ + @Deprecated public NoSuchBeanDefinitionException(Class type, String dependencyDescription, String message) { + this(ResolvableType.forClass(type), dependencyDescription, message); + } + + /** + * Create a new {@code NoSuchBeanDefinitionException}. + * @param resolvableType required type of the missing bean + * @param message detailed message describing the problem + */ + public NoSuchBeanDefinitionException(ResolvableType resolvableType, String message) { + this(resolvableType, resolvableType.toString(), message); + } + + /** + * Create a new {@code NoSuchBeanDefinitionException}. + * @param resolvableType required type of the missing bean + * @param dependencyDescription a description of the originating dependency + * @param message detailed message describing the problem + */ + private NoSuchBeanDefinitionException(ResolvableType resolvableType, String dependencyDescription, String message) { super("No qualifying bean" + (!StringUtils.hasLength(dependencyDescription) ? - " of type [" + ClassUtils.getQualifiedName(type) + "]" : "") + " found for dependency" + - (StringUtils.hasLength(dependencyDescription) ? " [" + dependencyDescription + "]" : "") + - ": " + message); - this.beanType = type; + " of type [" + ClassUtils.getQualifiedName(resolvableType.getRawClass()) + "]" : "") + + " found for dependency" + (StringUtils.hasLength(dependencyDescription) ? " [" + + dependencyDescription + "]" : "") + ": " + message); + this.beanResolvableType = resolvableType; } @@ -101,11 +124,19 @@ public class NoSuchBeanDefinitionException extends BeansException { return this.beanName; } + /** + * Return the required {@link ResolvableType} of the missing bean, if it was a lookup + * by type that failed. + */ + public ResolvableType getBeanResolvableType() { + return this.beanResolvableType; + } + /** * Return the required type of the missing bean, if it was a lookup by type that failed. */ public Class getBeanType() { - return this.beanType; + return this.beanResolvableType.getRawClass(); } /** 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 fba76f8d99..0ea02218f3 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 @@ -1081,7 +1081,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto Map matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { - raiseNoMatchingBeanFound(type, descriptor.getResolvableType().toString(), descriptor); + raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } @@ -1444,11 +1444,11 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto * for an unresolvable dependency. */ private void raiseNoMatchingBeanFound( - Class type, String dependencyDescription, DependencyDescriptor descriptor) throws BeansException { + Class type, ResolvableType resolvableType, DependencyDescriptor descriptor) throws BeansException { checkBeanNotOfRequiredType(type, descriptor); - throw new NoSuchBeanDefinitionException(type, dependencyDescription, + throw new NoSuchBeanDefinitionException(resolvableType, "expected at least 1 bean which qualifies as autowire candidate. " + "Dependency annotations: " + ObjectUtils.nullSafeToString(descriptor.getAnnotations())); }