SPRING源码分析--ResolvableType

Posted BLACK CAT JAVA

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPRING源码分析--ResolvableType相关的知识,希望对你有一定的参考价值。

SPRING源码分析--ResolvableType

JDK的Type类型

Type:是对java数据类型的分类抽象

首先所有的数据类型的类型都是Type,Class就是实现Type的接口

类图如下:

public class TypeTest {

   public static void main(String[] args) {

       Type type = TypeTest.class;
       System.out.println(type);
  }
}
//   控制台输出: class TypeTest

// Class.isPrimitive(),
// Class是否为原始类型(boolean、char、byte、short、int、long、float、double)是返回true  
class{
public String toString() {
       return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
           + getName();
  }
}


ParameterizedType  参数化类型  即泛型;例如:List<T>、Map<K,V>等带有参数化的对象;    

  
public  interface ParameterizedType extends Type{  
   //获取<> 里面的实际类型
   Type[] getActualTypeArguments();

   //获取<>前面的类型
   Type getRawType();

    //如果这个类型是某个所属,获取顶层所有者类型,反则返回为null
   //表示此类型是其成员之一的类型。例如,如果此类型为 O<T>.I<S>,则返回 O<T> 的表示形式。
   //如果此类型为顶层类型,则返回 null。
   Type getOwnerType();
}

public  class ParameterizedTypeDemo{
   public static void main(String[] args) {
       List<Integer> foo = new ArrayList<Integer>(){};
Type mySuperClass = foo.getClass().getGenericSuperclass();
Type pType = ((ParameterizedType)mySuperClass).getActualTypeArguments()[0];
System.out.println(pType);
Type rawType = ((ParameterizedType) mySuperClass).getRawType();
System.out.println(rawType);
Type ownerType = ((ParameterizedType) mySuperClass).getOwnerType();
System.out.println(ownerType);
  }
}

//控制台输出:
//class java.lang.Integer
//class java.util.ArrayList
//null


TypeVariable:代表泛型中的变量,比如下面的T就是TypeVariable类型

public interface TypeVariable<D extends GenericDeclaration> extends Type{
   //获取泛型的上限,默认为object
   Type[] getBounds();
   //获取声明该变量实体(即获取类、方法、构造器)
   D getGenericDeclaration();
   //获取名称,即D,K,V,E之类的名称
   String getName();
   
}


public class TypeVariableTest<T extends Number & Serializable> {

private T t;

public static void main(String[] args) throws NoSuchFieldException {
Field field = TypeVariableTest.class.getDeclaredField("t");
TypeVariable typeVariable = (TypeVariable) field.getGenericType();
       
Type[] types = typeVariable.getBounds();
for (Type type : types) {
System.out.println(type);
}
System.out.println(typeVariable.getName());

System.out.println(typeVariable.getGenericDeclaration());
}
}
//控制台输出
//class java.lang.Number
//interface java.io.Serializable
//T
//class com.black.cat.TypeVariableTest


WildcardType:代表泛型上界和下界。

List<? extends Fruit>定义了上界,?类型是Fruit的子类List<? super Apple>定义了下界,?类型是Apple的父类

public interface WildcardType extends Type {
   //获取上界
   Type[] getUpperBounds();

   //获取下界
   Type[] getLowerBounds();
}

public class WildcardTypeTest {

private List<? extends String> listStr;

private List<? super String> b;

public static void testGetBounds(String field) throws  NoSuchFieldException {

Field fieldNum = WildcardTypeTest.class.getDeclaredField(field);
Type typeNum = fieldNum.getGenericType();
ParameterizedType parameterizedTypeTypeNum = (ParameterizedType) typeNum;
Type[] typesNum = parameterizedTypeTypeNum.getActualTypeArguments();

WildcardType wildcardType = (WildcardType) typesNum[0];
{
Type[] types = wildcardType.getUpperBounds();
for (Type type : types) {
System.out.println("upper:"+type);
}

types = wildcardType.getLowerBounds();
for (Type type : types) {
System.out.println("lower:"+type);
}
}

}

public static void testGetUpperBounds() throws  NoSuchFieldException
{
testGetBounds("listStr");
testGetBounds("b");
}

public static void main(String[] args) throws NoSuchFieldException {
testGetUpperBounds();
}
}
//控制台输出
//upper:class java.lang.String
//upper:class java.lang.Object
//lower:class java.lang.String


GenericArrayType:泛型数组

public interface GenericArrayType extends Type {
   //获取这个数组的元素类型  
   Type getGenericComponentType();
}

public class GenericArrayTypeBean <T> {

// 属于 GenericArrayType
List<String>[] pTypeArray;

// 属于 GenericArrayType
T[] vTypeArray;

// 不属于 GenericArrayType
List<String> list;

// 不属于 GenericArrayType
String[] strings;

public static void testGetBounds(String field) throws  NoSuchFieldException {

Field fieldNum = GenericArrayTypeBean.class.getDeclaredField(field);
Type typeNum = fieldNum.getGenericType();

if(typeNum instanceof GenericArrayType){
GenericArrayType genericArrayType = (GenericArrayType) typeNum;
System.out.println(genericArrayType.getGenericComponentType());
}else {
System.out.println("不属于GenericArrayType:"+typeNum);
}


}

public static void testGetUpperBounds() throws  NoSuchFieldException
{
testGetBounds("pTypeArray");
testGetBounds("vTypeArray");
testGetBounds("list");
testGetBounds("strings");
}

public static void main(String[] args) throws NoSuchFieldException {
testGetUpperBounds();
}
//控制台输出
//java.util.List<java.lang.String>
// T
//不属于GenericArrayType:java.util.List<java.lang.String>
//不属于GenericArrayType:class [Ljava.lang.String;
}


Type的获取方式

通过Class获取Type

getSuperclass  返回直接继承的父类,getGenericSuperclass  返回直接继承的父类(包含泛型参数)

public class Test {

class Person<T> {
}

class Student extends Person<Test> {

}
 
public static void main(String[] args) {
       System.out.println("Student.class.getSuperclass()\n"
                           + Student.class.getSuperclass());
       System.out.println("Student.class.getGenericSuperclass()\n"
                           + Student.class.getGenericSuperclass());
  }

}

//控制台输出
//Student.class.getSuperclass()
//class com.black.cat.Test$Person
//Student.class.getGenericSuperclass()//com.black.cat.Test.com.black.cat.Test$Person<com.black.cat.Test>


通过Field获取Type

   getType和getGenericType方法

public class FieldTest {


   class Person<T> {

       public List<CharSequence> charSequenceList;

       public String str;
  }

   class Student extends Person<FieldTest> {


  }

   public static void main(String[] args) throws NoSuchFieldException {
       Field field = Student.class.getField("str");
System.out.println(field.getType());
System.out.println(field.getGenericType());

Field charField = Student.class.getField("charSequenceList");
System.out.println(charField.getType());
System.out.println(charField.getGenericType());
  }
}
//控制台输出
//class java.lang.String
//class java.lang.String
//interface java.util.List
//java.util.List<java.lang.CharSequence>


通过Method获取参数Type

Method是获取其参数或者返回值的Type,还有一个特殊的构造函数也可以归类为Method

public class MethodTest {

static class Person<T> {

}

static class Student extends Person<MethodTest> {


public Student(List<CharSequence> list) {

}

public Integer test(List<MethodTest> list) {
return null;
}

}

public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {

Method method = Student.class.getMethod("test", List.class);
Class type1 = method.getParameterTypes()[0];
Type type2 = method.getGenericParameterTypes()[0];
System.out.println(type1);
System.out.println(type2);


Constructor constructor = Student.class.getConstructor(List.class);
Class type3 = constructor.getParameterTypes()[0];
Type type4 = constructor.getGenericParameterTypes()[0];
System.out.println(type3);
System.out.println(type4);

}
}
//控制台输出
//interface java.util.List
//java.util.List<com.black.cat.MethodTest>
//interface java.util.List
//java.util.List<java.lang.CharSequence>


MethodParameter

Spring对方法的参数做了一个抽象封装,如参数和返回值都可以认为是一个MethodParameter可以使用MethodParameter.forMethodOrConstructor静态方法来构建一个MethodParameter

public class MethodParameterTests {

public static class TestItem {
public TestItem(List<String> list) {

}

public void m1(List<Integer> intParam) {

}
}


public static void main(String[] args) throws NoSuchMethodException {
Method method = TestItem.class.getMethod("m1", List.class);
MethodParameter parameter = MethodParameter.forMethodOrConstructor(method, 0);
System.out.println(parameter.getParameterType());
System.out.println(parameter.getGenericParameterType());

Constructor constructor = TestItem.class.getConstructor(List.class);
MethodParameter param = MethodParameter.forMethodOrConstructor(constructor, 0);
System.out.println(param.getParameterType());
System.out.println(param.getGenericParameterType());

}
}
//控制台输出
//interface java.util.List
//java.util.List<java.lang.Integer>
//interface java.util.List
//java.util.List<java.lang.String>


ResolvableType

ResolvableType是对Java类型的封装,提供了对父类(getSuperType())、接口(getInterfaces())、泛型参数(getGeneric(int...))的访问,最底层的实现为resolve()方法。ResolvableType可以通过forField(Field)、forMethodParameter(Method, int)、forMethodReturnType(Method)和forClass(Class)进行构造。这个类的大部分方法返回的都是ResolvableType类型,用户很容易地进行操作。

private HashMap<Integer, List<String>> myMap;

public void example() {
ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap"));
t.getSuperType(); // AbstractMap<Integer, List<String>>
t.asMap(); // Map<Integer, List<String>>
t.getGeneric(0).resolve(); // Integer
t.getGeneric(1).resolve(); // List
t.getGeneric(1); // List<String>
t.resolveGeneric(1, 0); // String
}


造获取 Field 的泛型信息

ResolvableType.forField(Field)

static class Fields<T> {
public List<T> parameterizedType;
}

@Test
public void resolveParameterizedType() throws Exception {
ResolvableType type = ResolvableType.forField(Fields.class.getField("parameterizedType"));
assertThat(type.resolve(), equalTo((Class) List.class));
}

构造获取 Method 的泛型信息

ResolvableType.forMethodParameter(Method, int)

interface Methods<T> {
void typedParameter(T p);
}
@Test
public void resolveTypeVariableFromMethodParameter() throws Exception {
Method method = Methods.class.getMethod("typedParameter", Object.class);
ResolvableType type = ResolvableType.forMethodParameter(method, 0);
assertThat(type.getType().toString(), equalTo("T"));
}

构造获取方法返回参数的泛型信息

ResolvableType.forMethodReturnType(Method)

interface Methods<T> {
T typedReturn();
}

@Test
public void resolveTypeVariableFromMethodReturn() throws Exception {
Method method = Methods.class.getMethod("typedReturn");
ResolvableType type = ResolvableType.forMethodReturnType(method);
assertThat(type.getType().toString(), equalTo("T"));
}

构造获取构造参数的泛型信息

ResolvableType.forConstructorParameter(Constructor, int)

static class Constructors<T> {

public Constructors(List<CharSequence> p) {
}

public Constructors(Map<T, Long> p) {
}
}

@Test
public void forConstructorParameter() throws Exception {
Constructor<Constructors> constructor = Constructors.class.getConstructor(List.class);
ResolvableType type = ResolvableType.forConstructorParameter(constructor, 0);
assertThat(type.getType(), equalTo(constructor.getGenericParameterTypes()[0]));
}

构造获取类的泛型信息

ResolvableType.forClass(Class)
static class ExtendsList extends ArrayList<CharSequence> {
}


public static void main(String[] args)throws Exception {
ResolvableType type = ResolvableType.forClass(ExtendsList.class);
System.out.println(type);
assertThat(type.getType(), equalTo((Type) ExtendsList.class));
assertThat(type.getRawClass(), equalTo(ExtendsList.class));
assertTrue(type.isAssignableFrom(ExtendsList.class));
assertFalse(type.isAssignableFrom(ArrayList.class));
}

public static ResolvableType forClass(@Nullable Class<?> clazz) {
return new ResolvableType(clazz);
}

//com.black.cat.ResolvableTypeTests$ExtendsList

构造获取类型的泛型信息

ResolvableType.forType(Type)
   
interface Methods<T> {
   T typedReturn();
}
@Test
public void resolveTypeVariableFromType() throws Exception {
Type sourceType = Methods.class.getMethod("typedReturn").getGenericReturnType();
ResolvableType type = ResolvableType.forType(sourceType);
assertThat(type.getType().toString(), equalTo("T"));
}

构造获取实例的泛型信息

ResolvableType.forInstance(Object)
@Test
public void forInstanceNoProvider() {
ResolvableType type = ResolvableType.forInstance(new Object());
assertThat(type.getType(), equalTo(Object.class));
assertThat(type.resolve(), equalTo(Object.class));
}



以上是关于SPRING源码分析--ResolvableType的主要内容,如果未能解决你的问题,请参考以下文章

Spring源码分析-Spring源码编译

Spring事务源码分析专题JdbcTemplate使用及源码分析

09Spring源码-分析篇-DI源码分析

Spring源码分析——源码分析环境搭建

Spring 循环引用源码分析

10Spring源码-分析篇-AOP源码分析