基于Spring中的泛型类型进行自动装配。它是如何工作的?

时间:2014-06-30 12:05:04

标签: java spring generics type-erasure

如您所知,Spring 4中有一项新功能:基于通用类型的自动装配。 它非常有用,但我想知道,Spring开发人员如何能够绕过类型擦除,这阻止了它们之前开发此类功能。

2 个答案:

答案 0 :(得分:9)

擦除意味着信息已从运行时中消失。它仍然存在于编译时信息中,您可以通过反射访问它们。在粗略的层面上,您可以认为有关单个实例的通用信息已被删除,但有关的一般信息则不会被删除。

例如,这是一个定义通用方法foo的简单程序,然后从main打印出有关它的通用信息:

import java.util.*;
import java.lang.reflect.*;

public class GenericReflection {
  public static void main(String[] args) throws Exception {
    Method m = GenericReflection.class.getDeclaredMethod("foo");
    System.out.println(m.getGenericReturnType());
  }

  public static List<String> foo() {
    return null;
  }
}

输出:

  

的java.util.List&LT; java.lang.String中&GT;

正如您所看到的,当您开始使用它时,它并不太复杂。

Method.getGenreicReturnType返回java.lang.reflect.Type,其中包含一些子类。一个是ParameterizedType,它有一个方法getActualTypeArguments,它返回此类型参数化的实际类型。当然,这些类型也可能是通用的,这就是它返回Type[]而不是Class[]的原因。在上面的foo示例中,它返回一个包含一个元素的数组,代表String

ParameterizedType pm = (ParameterizedType) m.getGenericReturnType();
Type[] pmArgs = pm.getActualTypeArguments();
System.out.println(Arrays.toString(pmArgs));
  

[class java.lang.String]

有类似的&#34;泛型&#34; Field.getGenericType的方法。您可以使用此信息来确定List<String>List参数化为String,这正是他们需要的信息。

答案 1 :(得分:3)

最重要的细节在Spring博客的this文章中。

正如您所看到的,所有魔法都隐藏在ResolvableType类中,您可以找到Javadoc here并且可以找到其代码here(它非常重阅读:))