Infer return type of parametrized factory methods
Currently, if a factory method is parameterized and the corresponding variable types are declared on the method itself instead of on the enclosing class or interface, Spring always predicts the return type to be Object, even if the return type can be explicitly inferred from the method signature and supplied arguments (which are available in the bean definition). This commit introduces a new resolveParameterizedReturnType() method in GenericTypeResolver that attempts to infer the concrete type for the generic return type of a given parameterized method, falling back to the standard return type if necessary. Furthermore, AbstractAutowireCapableBeanFactory now delegates to resolveParameterizedReturnType() when predicting the return type for factory methods. resolveParameterizedReturnType() is capable of inferring the concrete type for return type T for method signatures similar to the following. Such methods may potentially be static. Also, the formal argument list for such methods is not limited to a single argument. - public <T> T foo(Class<T> clazz) - public <T> T foo(Object obj, Class<T> clazz) - public <V, T> T foo(V obj, Class<T> clazz) - public <T> T foo(T obj) Issue: SPR-9493
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -29,6 +29,8 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.junit.Test;
|
||||
import test.beans.GenericBean;
|
||||
import test.beans.GenericIntegerBean;
|
||||
@@ -46,6 +48,7 @@ import org.springframework.core.io.UrlResource;
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
* @since 20.01.2006
|
||||
*/
|
||||
public class BeanFactoryGenericsTests {
|
||||
@@ -619,6 +622,30 @@ public class BeanFactoryGenericsTests {
|
||||
assertEquals(new URL("http://www.springframework.org"), us.iterator().next());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests support for parameterized {@code factory-method} declarations such
|
||||
* as EasyMock's {@code createMock()} method which has the following signature.
|
||||
*
|
||||
* <pre>{@code
|
||||
* public static <T> T createMock(Class<T> toMock)
|
||||
* }</pre>
|
||||
*
|
||||
* @since 3.2
|
||||
* @see SPR-9493
|
||||
*/
|
||||
@Test
|
||||
public void parameterizedFactoryMethod() {
|
||||
RootBeanDefinition rbd = new RootBeanDefinition(EasyMock.class);
|
||||
rbd.setFactoryMethodName("createMock");
|
||||
rbd.getConstructorArgumentValues().addGenericArgumentValue(Runnable.class);
|
||||
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
bf.registerBeanDefinition("easyMock", rbd);
|
||||
|
||||
Map<String, Runnable> beans = bf.getBeansOfType(Runnable.class);
|
||||
assertEquals(1, beans.size());
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class NamedUrlList extends LinkedList<URL> {
|
||||
|
||||
@@ -28,7 +28,6 @@ import test.beans.TestBean;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user