Refined throwing of BeanCreationExceptions (and reflection exceptions)

Issue: SPR-14883
This commit is contained in:
Juergen Hoeller 2016-11-07 19:03:18 +01:00
parent cf479bf893
commit b3cd1ad7f1
6 changed files with 18 additions and 43 deletions

View File

@ -355,7 +355,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
@Override @Override
public PropertyValues postProcessPropertyValues( public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try { try {
@ -404,15 +404,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
if (metadata != null) { if (metadata != null) {
metadata.clear(pvs); metadata.clear(pvs);
} }
try {
metadata = buildAutowiringMetadata(clazz); metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata); this.injectionMetadataCache.put(cacheKey, metadata);
} }
catch (NoClassDefFoundError err) {
throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() +
"] for autowiring metadata: could not find class that it depends on", err);
}
}
} }
} }
return metadata; return metadata;

View File

@ -145,8 +145,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>(); private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>();
/** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */ /** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */
private final Map<String, BeanWrapper> factoryBeanInstanceCache = private final Map<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>(16);
new ConcurrentHashMap<>(16);
/** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */ /** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */
private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache = private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
@ -536,7 +535,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
} }
catch (Throwable ex) { catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of bean type [" + beanType.getName() + "] failed", ex); "Post-processing of merged bean definition failed", ex);
} }
mbd.postProcessed = true; mbd.postProcessed = true;
} }
@ -721,8 +720,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
paramNames = pnd.getParameterNames(factoryMethod); paramNames = pnd.getParameterNames(factoryMethod);
} }
ConstructorArgumentValues cav = mbd.getConstructorArgumentValues(); ConstructorArgumentValues cav = mbd.getConstructorArgumentValues();
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
new HashSet<>(paramTypes.length);
Object[] args = new Object[paramTypes.length]; Object[] args = new Object[paramTypes.length];
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
ConstructorArgumentValues.ValueHolder valueHolder = cav.getArgumentValue( ConstructorArgumentValues.ValueHolder valueHolder = cav.getArgumentValue(
@ -952,12 +950,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @param mbd the merged bean definition for the bean * @param mbd the merged bean definition for the bean
* @param beanType the actual type of the managed bean instance * @param beanType the actual type of the managed bean instance
* @param beanName the name of the bean * @param beanName the name of the bean
* @throws BeansException if any post-processing failed
* @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition * @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
*/ */
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
throws BeansException {
for (BeanPostProcessor bp : getBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) { if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
@ -1000,12 +995,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @param beanClass the class of the bean to be instantiated * @param beanClass the class of the bean to be instantiated
* @param beanName the name of the bean * @param beanName the name of the bean
* @return the bean object to use instead of a default instance of the target bean, or {@code null} * @return the bean object to use instead of a default instance of the target bean, or {@code null}
* @throws BeansException if any post-processing failed
* @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation * @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
*/ */
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
throws BeansException {
for (BeanPostProcessor bp : getBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) { if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

View File

@ -17,8 +17,11 @@
package org.springframework.beans.factory.support; package org.springframework.beans.factory.support;
/** /**
* Internal exception to be propagated from {@link ConstructorResolver}. * Internal exception to be propagated from {@link ConstructorResolver},
* passed through to the initiating {@link DefaultSingletonBeanRegistry}
* (without wrapping in a {@code BeanCreationException}).
* *
* @author Juergen Hoeller
* @since 5.0 * @since 5.0
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")

View File

@ -336,15 +336,9 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
if (metadata != null) { if (metadata != null) {
metadata.clear(pvs); metadata.clear(pvs);
} }
try {
metadata = buildResourceMetadata(clazz); metadata = buildResourceMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata); this.injectionMetadataCache.put(cacheKey, metadata);
} }
catch (NoClassDefFoundError err) {
throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() +
"] for resource metadata: could not find class that it depends on", err);
}
}
} }
} }
return metadata; return metadata;

View File

@ -60,14 +60,12 @@ public abstract class ReflectionUtils {
* Cache for {@link Class#getDeclaredMethods()} plus equivalent default methods * Cache for {@link Class#getDeclaredMethods()} plus equivalent default methods
* from Java 8 based interfaces, allowing for fast iteration. * from Java 8 based interfaces, allowing for fast iteration.
*/ */
private static final Map<Class<?>, Method[]> declaredMethodsCache = private static final Map<Class<?>, Method[]> declaredMethodsCache = new ConcurrentReferenceHashMap<>(256);
new ConcurrentReferenceHashMap<>(256);
/** /**
* Cache for {@link Class#getDeclaredFields()}, allowing for fast iteration. * Cache for {@link Class#getDeclaredFields()}, allowing for fast iteration.
*/ */
private static final Map<Class<?>, Field[]> declaredFieldsCache = private static final Map<Class<?>, Field[]> declaredFieldsCache = new ConcurrentReferenceHashMap<>(256);
new ConcurrentReferenceHashMap<>(256);
/** /**

View File

@ -389,15 +389,9 @@ public class PersistenceAnnotationBeanPostProcessor
if (metadata != null) { if (metadata != null) {
metadata.clear(pvs); metadata.clear(pvs);
} }
try {
metadata = buildPersistenceMetadata(clazz); metadata = buildPersistenceMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata); this.injectionMetadataCache.put(cacheKey, metadata);
} }
catch (NoClassDefFoundError err) {
throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() +
"] for persistence metadata: could not find class that it depends on", err);
}
}
} }
} }
return metadata; return metadata;