源码分析:Spring 泛型解析 - ResolvableType

总结

1
2
3
4
5
6
7
8
9
10
11
12
--------------------------------------------------------------------
# 泛型解析 主要方法
ResolvableType#getGenerics

它会把每个运行的 class 类,进行递归解析 => 想要获取的时候,再根据 class 进行匹配
--------------------------------------------------------------------
类 ResolvableType#forClass
字段 ResolvableType#forField
方法参数 ResolvableType#forMethodParameter
方法返回值 ResolvableType#forMethodReturnType
构造方法参数 ResolvableType#forConstructorParameter
--------------------------------------------------------------------

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package com.taopanfeng.junit.spring._005_ResolvableType;

import cn.hutool.core.lang.TypeReference;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ResolvableType;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* 描述
*
* @author 陶攀峰
* @date 2024-05-11 10:41
*/
@Configuration
public class MyTest {

@Bean
public Map<String, String> strMap() {
return new HashMap<>();
}

@Bean
public Map<String, Object> objMap() {
return new HashMap<>();
}

// 2024-05-11 10:52
public static void main(String[] args) throws Throwable {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyTest.class);

// applicationContext.getBean(Map.class);// 不唯一

ObjectProvider<Map> beanProvider = applicationContext.getBeanProvider(Map.class);
List<Map> mapList = beanProvider.stream().collect(Collectors.toList());

String[] beanNamesForType = applicationContext.getBeanNamesForType(ResolvableType.forClassWithGenerics(
Map.class, String.class, String.class
));
String[] beanNamesForType1 = applicationContext.getBeanNamesForType(ResolvableType.forClassWithGenerics(
Map.class, String.class, Object.class
));
String[] beanNamesForType2 = applicationContext.getBeanNamesForType(ResolvableType.forClass(
Map.class
));


// 运行时,获取泛型参数:失败
Map<String, Map<Integer, Object>> map = new HashMap<>();
ResolvableType resolvableType = ResolvableType.forInstance(map);
ResolvableType g1 = resolvableType.getGeneric(0);// ? 解析失败
ResolvableType g2 = resolvableType.getGeneric(1);// ? 解析失败
ResolvableType superType = resolvableType.getSuperType();// java.util.AbstractMap<?, ?>

// 运行时,获取泛型参数:成功
TypeReference<Map<String, Map<Integer, Object>>> typeRef = new TypeReference<Map<String, Map<Integer, Object>>>() {
};
ResolvableType resolvableType1 = ResolvableType.forInstance(typeRef);

ResolvableType generic = resolvableType1.getSuperType().getGeneric(0);// java.util.Map<java.lang.String, java.util.Map<java.lang.Integer, java.lang.Object>>
ResolvableType generic1 = resolvableType1.getSuperType().getGeneric(0, 0);// java.lang.String
ResolvableType generic2 = resolvableType1.getSuperType().getGeneric(0, 1);// java.util.Map<java.lang.Integer, java.lang.Object>
ResolvableType generic3 = resolvableType1.getSuperType().getGeneric(0, 1, 0);// java.lang.Integer
ResolvableType generic4 = resolvableType1.getSuperType().getGeneric(0, 1, 1);// java.lang.Object
ResolvableType generic5 = resolvableType1.getSuperType().getGeneric(0, 1, 2);// ? 解析失败
ResolvableType generic6 = resolvableType1.getSuperType().getGeneric(999);// ? 解析失败
}

}