Refined throwing of BeanCreationExceptions (and reflection exceptions)

Issue: SPR-14883
This commit is contained in:
Juergen Hoeller
2016-11-07 18:47:54 +01:00
parent b42d731fc8
commit 3d2e4c338c
6 changed files with 52 additions and 80 deletions

View File

@@ -243,23 +243,28 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
// Let's check for lookup methods here..
if (!this.lookupMethodsChecked.contains(beanName)) {
ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
try {
ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
}
}
});
});
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
this.lookupMethodsChecked.add(beanName);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 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.
@@ -103,7 +103,6 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
* @see org.springframework.beans.MutablePropertyValues
*/
PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException;
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 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.
@@ -68,6 +68,7 @@ public interface Scope {
* @param objectFactory the {@link ObjectFactory} to use to create the scoped
* object if it is not present in the underlying storage mechanism
* @return the desired object (never {@code null})
* @throws IllegalStateException if the underlying scope is not currently active
*/
Object get(String name, ObjectFactory<?> objectFactory);
@@ -84,6 +85,7 @@ public interface Scope {
* removing an object.
* @param name the name of the object to remove
* @return the removed object, or {@code null} if no object was present
* @throws IllegalStateException if the underlying scope is not currently active
* @see #registerDestructionCallback
*/
Object remove(String name);
@@ -112,6 +114,7 @@ public interface Scope {
* so it can safely be executed without an enclosing try-catch block.
* Furthermore, the Runnable will usually be serializable, provided
* that its target object is serializable as well.
* @throws IllegalStateException if the underlying scope is not currently active
* @see org.springframework.beans.factory.DisposableBean
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#getDestroyMethodName()
* @see DestructionAwareBeanPostProcessor
@@ -123,6 +126,7 @@ public interface Scope {
* E.g. the HttpServletRequest object for key "request".
* @param key the contextual key
* @return the corresponding object, or {@code null} if none found
* @throws IllegalStateException if the underlying scope is not currently active
*/
Object resolveContextualObject(String key);
@@ -139,6 +143,7 @@ public interface Scope {
* underlying storage mechanism has no obvious candidate for such an ID.
* @return the conversation ID, or {@code null} if there is no
* conversation ID for the current scope
* @throws IllegalStateException if the underlying scope is not currently active
*/
String getConversationId();

View File

@@ -479,21 +479,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException ex) {
// A previously detected exception with proper bean creation context already...
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
/**
@@ -532,7 +522,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing failed of bean type [" + beanType + "] failed", ex);
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
@@ -948,12 +938,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @param mbd the merged bean definition for the bean
* @param beanType the actual type of the managed bean instance
* @param beanName the name of the bean
* @throws BeansException if any post-processing failed
* @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
*/
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName)
throws BeansException {
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
@@ -996,12 +983,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @param beanClass the class of the bean to be instantiated
* @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}
* @throws BeansException if any post-processing failed
* @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
*/
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
throws BeansException {
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

View File

@@ -214,7 +214,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while the singletons of this factory are in destruction " +
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {