diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanInstantiationException.java b/spring-beans/src/main/java/org/springframework/beans/BeanInstantiationException.java index 09190f6f121..d8f7d246091 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanInstantiationException.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanInstantiationException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 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. @@ -16,6 +16,9 @@ package org.springframework.beans; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + /** * Exception thrown when instantiation of a bean failed. * Carries the offending bean class. @@ -28,6 +31,10 @@ public class BeanInstantiationException extends FatalBeanException { private Class beanClass; + private Constructor constructor; + + private Method constructingMethod; + /** * Create a new BeanInstantiationException. @@ -49,12 +56,60 @@ public class BeanInstantiationException extends FatalBeanException { this.beanClass = beanClass; } + /** + * Create a new BeanInstantiationException. + * @param constructor the offending constructor + * @param msg the detail message + * @param cause the root cause + * @since 4.3 + */ + public BeanInstantiationException(Constructor constructor, String msg, Throwable cause) { + super("Failed to instantiate [" + constructor.getDeclaringClass().getName() + "]: " + msg, cause); + this.beanClass = constructor.getDeclaringClass(); + this.constructor = constructor; + } /** - * Return the offending bean class. + * Create a new BeanInstantiationException. + * @param constructingMethod the delegate for bean construction purposes + * (typically, but not necessarily, a static factory method) + * @param msg the detail message + * @param cause the root cause + * @since 4.3 + */ + public BeanInstantiationException(Method constructingMethod, String msg, Throwable cause) { + super("Failed to instantiate [" + constructingMethod.getReturnType().getName() + "]: " + msg, cause); + this.beanClass = constructingMethod.getReturnType(); + this.constructingMethod = constructingMethod; + } + + + /** + * Return the offending bean class (never {@code null}). + * @return the class that was to be instantiated */ public Class getBeanClass() { return this.beanClass; } + /** + * Return the offending constructor, if known. + * @return the constructor in use, or {@code null} in case of a + * factory method or in case of default instantiation + * @since 4.3 + */ + public Constructor getConstructor() { + return this.constructor; + } + + /** + * Return the delegate for bean construction purposes, if known. + * @return the method in use (typically a static factory method), + * or {@code null} in case of constructor-based instantiation + * @since 4.3 + */ + public Method getConstructingMethod() { + return this.constructingMethod; + } + } diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index 5c735f16fb6..512ddddb8a3 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -147,20 +147,16 @@ public abstract class BeanUtils { return ctor.newInstance(args); } catch (InstantiationException ex) { - throw new BeanInstantiationException(ctor.getDeclaringClass(), - "Is it an abstract class?", ex); + throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex); } catch (IllegalAccessException ex) { - throw new BeanInstantiationException(ctor.getDeclaringClass(), - "Is the constructor accessible?", ex); + throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex); } catch (IllegalArgumentException ex) { - throw new BeanInstantiationException(ctor.getDeclaringClass(), - "Illegal arguments for constructor", ex); + throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex); } catch (InvocationTargetException ex) { - throw new BeanInstantiationException(ctor.getDeclaringClass(), - "Constructor threw exception", ex.getTargetException()); + throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException()); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java index f878c57ed06..74acbd2fee1 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 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. @@ -171,12 +171,12 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy { } } catch (IllegalArgumentException ex) { - throw new BeanInstantiationException(factoryMethod.getReturnType(), + throw new BeanInstantiationException(factoryMethod, "Illegal arguments to factory method '" + factoryMethod.getName() + "'; " + "args: " + StringUtils.arrayToCommaDelimitedString(args), ex); } catch (IllegalAccessException ex) { - throw new BeanInstantiationException(factoryMethod.getReturnType(), + throw new BeanInstantiationException(factoryMethod, "Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex); } catch (InvocationTargetException ex) { @@ -186,7 +186,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy { msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " + "declaring the factory method as static for independence from its containing instance. " + msg; } - throw new BeanInstantiationException(factoryMethod.getReturnType(), msg, ex.getTargetException()); + throw new BeanInstantiationException(factoryMethod, msg, ex.getTargetException()); } }