Browse Source

Expose ResolvableType in NoSuchBeanDefinitionException

This commit improves NoSuchBeanDefinitionException to expose a full
ResolvableType rather than a raw class if a lookup by type failed. This
allows to know more about the underlying type and is typically useful
when a collection or map is required as the relevant generic type is the
actual bean that wasn't found.

Issue: SPR-14831
pull/1221/head
Stephane Nicoll 8 years ago
parent
commit
b7d85f8ebc
  1. 47
      spring-beans/src/main/java/org/springframework/beans/factory/NoSuchBeanDefinitionException.java
  2. 6
      spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

47
spring-beans/src/main/java/org/springframework/beans/factory/NoSuchBeanDefinitionException.java

@ -17,6 +17,7 @@ @@ -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; @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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
* <em>by type</em> that failed.
*/
public ResolvableType getBeanResolvableType() {
return this.beanResolvableType;
}
/**
* 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 this.beanResolvableType.getRawClass();
}
/**

6
spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

@ -1081,7 +1081,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -1081,7 +1081,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
Map<String, Object> 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 @@ -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()));
}

Loading…
Cancel
Save