Better error reporting when instance does not match factory method

This commit improves the handling of IllegalArgumentException in
SimpleInstantiationStrategy. Previously, only arguments mismatch were
handled but the exception can also be thrown if the factory instance
does not match the target method.

Closes gh-28897
This commit is contained in:
Stéphane Nicoll 2023-10-24 13:25:06 +02:00
parent 6299a9dfc9
commit 999b5d4462
2 changed files with 53 additions and 0 deletions

View File

@ -36,6 +36,7 @@ import org.springframework.util.StringUtils;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Stephane Nicoll
* @since 1.1
*/
public class SimpleInstantiationStrategy implements InstantiationStrategy {
@ -152,6 +153,12 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
}
}
catch (IllegalArgumentException ex) {
if (factoryBean != null
&& !factoryMethod.getDeclaringClass().isAssignableFrom(factoryBean.getClass())) {
throw new BeanInstantiationException(factoryMethod,
"Illegal factory instance for factory method '" + factoryMethod.getName() + "'; " +
"instance: " + factoryBean.getClass().getName(), ex);
}
throw new BeanInstantiationException(factoryMethod,
"Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +
"args: " + StringUtils.arrayToCommaDelimitedString(args), ex);

View File

@ -53,6 +53,14 @@ class SimpleInstantiationStrategyTests {
assertThat(simpleBean).isEqualTo("Test42");
}
@Test
void instantiateWitSubClassFactoryArgs() {
RootBeanDefinition bd = new RootBeanDefinition(String.class);
Object simpleBean = instantiate(bd, new ExtendedSampleFactory(),
method(SampleFactory.class, "beanWithTwoArgs"), "Test", 42);
assertThat(simpleBean).isEqualTo("42Test");
}
@Test
void instantiateWithNullValueReturnsNullBean() {
RootBeanDefinition bd = new RootBeanDefinition(String.class);
@ -71,6 +79,28 @@ class SimpleInstantiationStrategyTests {
.withMessageContaining("args: 42,Test");
}
@Test
void instantiateWithTargetTypeMismatch() {
RootBeanDefinition bd = new RootBeanDefinition(String.class);
assertThatExceptionOfType(BeanInstantiationException.class).isThrownBy(() -> instantiate(
bd, new AnotherFactory(),
method(SampleFactory.class, "beanWithTwoArgs"), "Test", 42))
.withMessageContaining("Illegal factory instance for factory method 'beanWithTwoArgs'")
.withMessageContaining("instance: " + AnotherFactory.class.getName())
.withMessageNotContaining("args: Test,42");
}
@Test
void instantiateWithTargetTypeNotAssignable() {
RootBeanDefinition bd = new RootBeanDefinition(String.class);
assertThatExceptionOfType(BeanInstantiationException.class).isThrownBy(() -> instantiate(
bd, new SampleFactory(),
method(ExtendedSampleFactory.class, "beanWithTwoArgs"), "Test", 42))
.withMessageContaining("Illegal factory instance for factory method 'beanWithTwoArgs'")
.withMessageContaining("instance: " + SampleFactory.class.getName())
.withMessageNotContaining("args: Test,42");
}
@Test
void instantiateWithException() {
RootBeanDefinition bd = new RootBeanDefinition(String.class);
@ -115,4 +145,20 @@ class SimpleInstantiationStrategyTests {
}
}
static class ExtendedSampleFactory extends SampleFactory {
@Override
String beanWithTwoArgs(String first, Integer second) {
return second + first;
}
}
static class AnotherFactory {
String beanWithTwoArgs(String first, Integer second) {
return second + first;
}
}
}