类型系统 - ResolvableType
概述
ResolvableType 是 Spring Framework 提供的用于解决 Java 泛型擦除问题的核心类。它允许在运行时获取和操作泛型类型信息,是 Spring 依赖注入、数据绑定、AOP 代理等功能的基石。
核心能力矩阵
| 能力 | 核心类 | 解决的问题 | 使用频率 | 学习优先级 |
|---|---|---|---|---|
| 类型系统 | ResolvableType | Java 泛型擦除问题 | ⭐⭐⭐⭐⭐ | 🔴 高 |
1. 代码结构深度分析
1.0 源码位置与模块归属
spring-core
└── src/main/java/org/springframework/core
└── ResolvableType.java # 核心类
└── SerializableTypeWrapper.java # 类型包装器
└── ConcurrentReferenceHashMap.java # 缓存实现设计目标:
- 解决泛型擦除 - 在运行时保留泛型类型信息
- 统一类型操作 - 提供一致的API处理各种Type子类型
- 性能优化 - 通过缓存减少重复解析开销
- 线程安全 - 支持并发环境下的类型解析
1.1 整体架构
1.2 核心字段分析
java
public class ResolvableType implements Serializable {
// ========== 核心状态字段 ==========
/**
* 原始类型(Type是Java反射的顶层接口)
* 可能是:Class、ParameterizedType、GenericArrayType、WildcardType、TypeVariable
*/
private final Type type;
/**
* 数组组件类型
* 如果当前类型是数组(如 String[]),则存储组件类型(String)
*/
private final ResolvableType componentType;
/**
* 泛型参数数组
* 例如:Map<String, Integer> 存储 [String, Integer]
*/
private final ResolvableType[] generics;
/**
* 解析后的Class对象
* 缓存解析结果,避免重复解析
*/
private final Class<?> resolved;
/**
* 变量解析器
* 用于解析泛型变量(如 T、K、V)为实际类型
*/
private final VariableResolver variableResolver;
// ========== 单例 ==========
/**
* 空类型单例
* 用于表示无法解析的类型
*/
public static final ResolvableType NONE = new ResolvableType(null, null, null, null);
// ========== 缓存 ==========
/**
* 全局缓存,使用软引用
* Key: ResolvableType(作为查找键)
* Value: ResolvableType(缓存的实例)
*/
private static final ConcurrentReferenceHashMap<ResolvableType, ResolvableType>
cache = new ConcurrentReferenceHashMap<>(256);
}1.3 工厂方法详解
java
public class ResolvableType {
/**
* 从Class创建ResolvableType
* 最简单的方式,适用于无泛型的类
*
* 示例:ResolvableType.forClass(String.class)
* 结果:表示 String 类型,无泛型参数
*/
public static ResolvableType forClass(Class<?> clazz) {
return new ResolvableType(clazz);
}
/**
* 从字段创建ResolvableType
* 自动解析字段声明中的泛型信息
*
* 示例:
* class Config {
* private List<String> names;
* }
* ResolvableType.forField(Config.class.getDeclaredField("names"))
* 结果:表示 List<String>,可获取泛型参数 String
*/
public static ResolvableType forField(Field field) {
Assert.notNull(field, "Field must not be null");
return forType(field.getGenericType(),
new DefaultVariableResolver(field.getDeclaringClass()));
}
/**
* 从字段创建,指定实现类
* 用于解析继承场景中的泛型替换
*
* 示例:
* class Base<T> {
* private List<T> items;
* }
* class Child extends Base<String> {}
*
* forField(Base.class.getDeclaredField("items"), Child.class)
* 结果:表示 List<String>(T被替换为String)
*/
public static ResolvableType forField(Field field, Class<?> implementingClass) {
Assert.notNull(field, "Field must not be null");
return forType(field.getGenericType(),
new TypeVariableResolver(implementingClass));
}
/**
* 从方法参数创建ResolvableType
*
* 示例:
* void save(List<String> items, Map<String, Integer> metadata)
* forMethodParameter(method, 0) -> List<String>
* forMethodParameter(method, 1) -> Map<String, Integer>
*/
public static ResolvableType forMethodParameter(Method method, int parameterIndex) {
Assert.notNull(method, "Method must not be null");
MethodParameter methodParam = new MethodParameter(method, parameterIndex);
return forMethodParameter(methodParam);
}
/**
* 从方法返回类型创建ResolvableType
* 考虑类继承关系中的泛型替换
*
* 示例:
* interface Repository<T> {
* List<T> findAll();
* }
* class UserRepository implements Repository<User> {
* public List<User> findAll() { ... }
* }
*
* forMethodReturnType(findAllMethod, UserRepository.class)
* 结果:表示 List<User>
*/
public static ResolvableType forMethodReturnType(Method method, Class<?> implementingClass) {
Assert.notNull(method, "Method must not be null");
Type genericReturnType = method.getGenericReturnType();
return forType(genericReturnType, new TypeVariableResolver(implementingClass));
}
/**
* 从构造器参数创建ResolvableType
*/
public static ResolvableType forConstructorParameter(Constructor<?> constructor, int parameterIndex) {
Assert.notNull(constructor, "Constructor must not be null");
MethodParameter methodParam = new MethodParameter(constructor, parameterIndex);
return forMethodParameter(methodParam);
}
/**
* 带缓存的工厂方法(内部使用)
* 相同的Type会返回相同的ResolvableType实例
*/
public static ResolvableType forType(Type type, VariableResolver variableResolver) {
if (type == null) {
return NONE;
}
// 构建缓存键
ResolvableType key = new ResolvableType(type, variableResolver);
// 尝试从缓存获取
ResolvableType cached = cache.get(key);
if (cached != null) {
return cached;
}
// 创建新的ResolvableType
ResolvableType result = new ResolvableType(type, variableResolver, null, null);
// 放入缓存(如果已存在则使用已存在的)
ResolvableType existing = cache.putIfAbsent(key, result);
return existing != null ? existing : result;
}
}1.4 核心解析方法详解
java
public class ResolvableType {
/**
* 解析为具体Class
* 如果无法解析返回null
*
* 示例:
* - List<String>.resolve() -> List.class
* - String.resolve() -> String.class
* - T(未绑定).resolve() -> null
*/
public Class<?> resolve() {
if (this.resolved != null) {
return this.resolved;
}
if (this.type == null) {
return null;
}
return resolveClass();
}
/**
* 解析为指定类型的Class
* 如果解析结果不是expectedType的子类,返回null
*
* 示例:
* List<String>.resolve(Collection.class) -> List.class
* List<String>.resolve(Map.class) -> null
*/
public Class<?> resolve(Class<?> expectedType) {
Class<?> resolved = resolve();
if (resolved == null || expectedType.isAssignableFrom(resolved)) {
return resolved;
}
return null;
}
/**
* 获取指定位置的泛型参数
*
* 示例:
* Map<String, Integer>.getGeneric(0) -> String
* Map<String, Integer>.getGeneric(1) -> Integer
* List<String>.getGeneric(0) -> String
*/
public ResolvableType getGeneric(int index) {
if (this.generics == null || index < 0 || index >= this.generics.length) {
return NONE;
}
return this.generics[index];
}
/**
* 获取所有泛型参数
*/
public ResolvableType[] getGenerics() {
return this.generics != null ? this.generics : new ResolvableType[0];
}
/**
* 将当前类型视为指定类的子类型,解析其泛型
*
* 核心算法:
* 1. 检查当前类型是否已经是目标类型的子类型
* 2. 如果不是,递归检查父类和接口
* 3. 返回目标类型的泛型绑定
*
* 示例:
* class UserService implements BaseService<User, Long> {}
*
* forClass(UserService.class).as(BaseService.class)
* 返回:BaseService<User, Long> 的 ResolvableType
*
* 然后可以:
* .getGeneric(0).resolve() -> User.class
* .getGeneric(1).resolve() -> Long.class
*/
public ResolvableType as(Class<?> type) {
if (this.resolved == null || type.isAssignableFrom(this.resolved)) {
return this;
}
// 递归查找父类
ResolvableType superType = getSuperType();
if (superType != NONE) {
ResolvableType asType = superType.as(type);
if (asType != NONE) {
return asType;
}
}
// 递归查找接口
for (ResolvableType interfaceType : getInterfaces()) {
ResolvableType asType = interfaceType.as(type);
if (asType != NONE) {
return asType;
}
}
return NONE;
}
/**
* 获取父类型的ResolvableType
*
* 示例:
* class Child extends Parent<String> {}
* forClass(Child.class).getSuperType()
* 返回:Parent<String> 的 ResolvableType
*/
public ResolvableType getSuperType() {
Class<?> resolved = resolve();
if (resolved == null || resolved.getSuperclass() == null) {
return NONE;
}
Type superType = resolved.getGenericSuperclass();
return forType(superType, asVariableResolver());
}
/**
* 获取所有接口的ResolvableType
*
* 示例:
* class MyClass implements Interface1<String>, Interface2<Integer> {}
* getInterfaces() 返回 [Interface1<String>, Interface2<Integer>]
*/
public ResolvableType[] getInterfaces() {
Class<?> resolved = resolve();
if (resolved == null) {
return new ResolvableType[0];
}
Type[] interfaces = resolved.getGenericInterfaces();
ResolvableType[] result = new ResolvableType[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
result[i] = forType(interfaces[i], asVariableResolver());
}
return result;
}
/**
* 检查当前类型是否可以从其他类型赋值
* 支持数组、泛型、通配符等复杂类型检查
*
* 示例:
* List<String>.isAssignableFrom(ArrayList<String>) -> true
* List<String>.isAssignableFrom(List<Integer>) -> false
* String[].isAssignableFrom(String[]) -> true
*/
public boolean isAssignableFrom(ResolvableType other) {
if (this == NONE || other == NONE) {
return false;
}
// 处理数组类型
if (isArray()) {
return other.isArray() &&
getComponentType().isAssignableFrom(other.getComponentType());
}
// 处理泛型类型
if (resolved == null || other.resolved == null) {
return true;
}
return resolved.isAssignableFrom(other.resolved);
}
/**
* 检查是否为数组类型
*/
public boolean isArray() {
if (this == NONE) {
return false;
}
return (this.type instanceof Class && ((Class<?>) this.type).isArray()) ||
this.type instanceof GenericArrayType ||
this.componentType != null;
}
/**
* 获取数组组件类型
*
* 示例:
* String[].getComponentType() -> String
* List<String>[].getComponentType() -> List<String>
*/
public ResolvableType getComponentType() {
if (this == NONE) {
return NONE;
}
if (this.componentType != null) {
return this.componentType;
}
if (this.type instanceof Class) {
Class<?> componentType = ((Class<?>) this.type).getComponentType();
return forClass(componentType);
}
return NONE;
}
/**
* 获取嵌套泛型(多级泛型)
*
* 示例:
* Map<String, List<Integer>>
* .getNested(1, 0) 获取 List<Integer> 的第0个泛型 -> Integer
*/
public ResolvableType getNested(int... indexes) {
ResolvableType result = this;
for (int index : indexes) {
result = result.getGeneric(index);
}
return result;
}
}1.5 VariableResolver 变量解析器
java
/**
* 变量解析器接口
* 用于将泛型变量(如 T、K、V)解析为实际类型
*/
interface VariableResolver extends Serializable {
/**
* 解析泛型变量
* @param variable 泛型变量(如 T)
* @return 解析后的ResolvableType,如果无法解析返回null
*/
ResolvableType resolveVariable(TypeVariable<?> variable);
}
/**
* 默认变量解析器
* 基于声明类的泛型信息解析
*/
class DefaultVariableResolver implements VariableResolver {
private final Class<?> source;
public DefaultVariableResolver(Class<?> source) {
this.source = source;
}
@Override
public ResolvableType resolveVariable(TypeVariable<?> variable) {
return ResolvableType.forType(variable, this);
}
}
/**
* 类型变量解析器
* 用于解析继承场景中的泛型替换
*/
class TypeVariableResolver implements VariableResolver {
private final Class<?> contextClass;
public TypeVariableResolver(Class<?> contextClass) {
this.contextClass = contextClass;
}
@Override
public ResolvableType resolveVariable(TypeVariable<?> variable) {
// 在类层次结构中查找泛型变量的实际绑定
ResolvableType resolved = resolveVariableInHierarchy(variable, this.contextClass);
if (resolved != null) {
return resolved;
}
return ResolvableType.forType(variable);
}
private ResolvableType resolveVariableInHierarchy(TypeVariable<?> variable, Class<?> clazz) {
// 1. 检查当前类的泛型参数
// 2. 递归检查父类
// 3. 递归检查接口
// 返回找到的泛型绑定
// ...
return null;
}
}1.6 缓存机制详解
java
public class ResolvableType {
/**
* 并发引用HashMap - Spring自定义实现
* 特点:
* 1. 线程安全(使用分段锁)
* 2. 支持软引用/弱引用作为键或值
* 3. 自动清理被GC回收的条目
*/
private static final ConcurrentReferenceHashMap<ResolvableType, ResolvableType>
cache = new ConcurrentReferenceHashMap<>(256);
/**
* 缓存键的设计
* ResolvableType作为键时,使用以下字段计算hashCode和equals:
* - type
* - variableResolver
*
* 这样可以确保相同Type和相同解析器的查询返回缓存结果
*/
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (!(other instanceof ResolvableType)) return false;
ResolvableType that = (ResolvableType) other;
return Objects.equals(this.type, that.type) &&
Objects.equals(this.variableResolver, that.variableResolver);
}
@Override
public int hashCode() {
return Objects.hash(this.type, this.variableResolver);
}
/**
* 清空缓存
* 在类加载器被回收时调用,防止内存泄漏
*/
public static void clearCache() {
cache.clear();
}
}1.7 内部类结构关系
1.8 核心算法流程
2. 主要使用场景
2.1 场景分类总览
2.2 场景矩阵分析
| 场景 | 核心问题 | 使用API | 调用频率 | 性能要求 |
|---|---|---|---|---|
| 泛型依赖注入 | 解析Bean的泛型类型参数 | forClass() + as() + getGeneric() | 高(启动时) | 中等 |
| 数据绑定 | 将请求参数绑定到泛型集合 | forField() + getGeneric() | 高(运行时) | 高 |
| AOP代理 | 保留代理对象的泛型信息 | forClass() + as() | 中(启动时) | 中等 |
| 类型转换 | 支持泛型类型的转换 | forMethodParameter() + resolve() | 高(运行时) | 高 |
| 事件驱动 | 泛型事件的精确匹配 | forClass() + isAssignableFrom() | 中(运行时) | 中等 |
| 仓库元数据 | 解析Repository的实体类型 | forClass() + as() + getGeneric() | 低(启动时) | 低 |
2.3 场景1:泛型依赖注入(核心场景)
2.3.1 场景描述
在Spring容器中,当需要注入泛型类型的Bean时,必须能够区分不同泛型参数的Bean实例。
java
/**
* 场景:Spring需要注入泛型类型的依赖
*
* 示例:
* @Service
* public class UserService {
* @Autowired
* private Repository<User> userRepository; // 需要知道是 Repository<User>
* }
*/2.3.2 问题分析
2.3.3 Spring内部实现
java
// Spring内部使用ResolvableType解析注入点
public class GenericTypeResolver {
/**
* 解析单个泛型参数
* 使用频率:⭐⭐⭐⭐⭐
*/
public static Class<?> resolveTypeArgument(Class<?> clazz, Class<?> genericIfc) {
// 使用ResolvableType解析泛型参数
ResolvableType resolvableType = ResolvableType.forClass(clazz).as(genericIfc);
if (!resolvableType.hasGenerics()) {
return null;
}
return resolvableType.getGeneric(0).resolve();
}
/**
* 解析所有泛型参数
* 使用频率:⭐⭐⭐⭐
*/
public static Class<?>[] resolveTypeArguments(Class<?> clazz, Class<?> genericIfc) {
ResolvableType resolvableType = ResolvableType.forClass(clazz).as(genericIfc);
if (!resolvableType.hasGenerics()) {
return null;
}
ResolvableType[] generics = resolvableType.getGenerics();
Class<?>[] result = new Class[generics.length];
for (int i = 0; i < generics.length; i++) {
result[i] = generics[i].resolve();
}
return result;
}
}2.3.4 实际使用示例
java
public class DependencyInjectionExample {
// 场景1:解析Repository的泛型参数
public void resolveRepositoryGeneric() {
// UserRepository extends JpaRepository<User, Long>
Class<?> entityClass = GenericTypeResolver.resolveTypeArgument(
UserRepository.class, Repository.class);
// 结果:User.class
Class<?>[] typeArgs = GenericTypeResolver.resolveTypeArguments(
UserRepository.class, Repository.class);
// 结果:[User.class, Long.class]
}
// 场景2:解析Service的泛型参数
public void resolveServiceGeneric() {
// UserService extends BaseService<User, Long>
ResolvableType serviceType = ResolvableType.forClass(UserService.class);
ResolvableType baseServiceType = serviceType.as(BaseService.class);
Class<?> entityClass = baseServiceType.getGeneric(0).resolve(); // User.class
Class<?> idClass = baseServiceType.getGeneric(1).resolve(); // Long.class
}
// 场景3:复杂继承层次
public void resolveComplexHierarchy() {
// AbstractService<T, ID> implements BaseService<T, ID>
// UserService extends AbstractService<User, Long>
ResolvableType type = ResolvableType.forClass(UserService.class);
// 向上查找BaseService的泛型绑定
ResolvableType baseService = type.as(BaseService.class);
// 结果:BaseService<User, Long>
// 获取泛型参数
Class<?> t = baseService.getGeneric(0).resolve(); // User.class
Class<?> id = baseService.getGeneric(1).resolve(); // Long.class
}
}2.3 场景2:数据绑定
java
/**
* 场景:Spring MVC将请求参数绑定到泛型对象
*
* 示例:
* @PostMapping("/users")
* public ResponseEntity<List<User>> createUsers(@RequestBody List<User> users) {
* // 需要将JSON数组转换为List<User>
* }
*/
public class DataBindingExample {
/**
* 解析方法参数的泛型类型
*/
public void resolveMethodParameter() throws NoSuchMethodException {
Method method = UserController.class.getMethod("createUsers", List.class);
// 获取第0个参数的ResolvableType
ResolvableType paramType = ResolvableType.forMethodParameter(method, 0);
// 解析为List.class
Class<?> rawClass = paramType.resolve(); // List.class
// 获取泛型参数User.class
Class<?> genericClass = paramType.getGeneric(0).resolve(); // User.class
System.out.println("参数类型:" + rawClass.getName());
System.out.println("泛型类型:" + genericClass.getName());
}
/**
* 解析嵌套泛型
*/
public void resolveNestedGeneric() throws NoSuchMethodException {
// 方法签名:void process(Map<String, List<Integer>> data)
Method method = Processor.class.getMethod("process", Map.class);
ResolvableType paramType = ResolvableType.forMethodParameter(method, 0);
// 获取Map的键类型:String
ResolvableType keyType = paramType.getGeneric(0);
System.out.println("Map Key: " + keyType.resolve()); // String.class
// 获取Map的值类型:List<Integer>
ResolvableType valueType = paramType.getGeneric(1);
System.out.println("Map Value Raw: " + valueType.resolve()); // List.class
// 获取List的泛型:Integer
ResolvableType nestedType = valueType.getGeneric(0);
System.out.println("List Generic: " + nestedType.resolve()); // Integer.class
}
/**
* 解析返回类型
*/
public void resolveReturnType() throws NoSuchMethodException {
// 方法签名:ResponseEntity<List<User>> getUsers()
Method method = UserController.class.getMethod("getUsers");
ResolvableType returnType = ResolvableType.forMethodReturnType(
method, UserController.class);
// ResponseEntity -> List<User> -> User
ResolvableType bodyType = returnType.getGeneric(0); // List<User>
Class<?> userClass = bodyType.getGeneric(0).resolve(); // User.class
System.out.println("返回的实体类型:" + userClass.getName());
}
}2.4 场景3:AOP代理类型推断
java
/**
* 场景:Spring AOP创建代理时需要知道目标类型的泛型信息
*
* 示例:
* Repository<User> repository = (Repository<User>) proxyFactory.getProxy();
* 需要确保代理对象保留了泛型信息
*/
public class AopTypeInferenceExample {
/**
* 获取代理的目标泛型类型
*/
public void resolveProxyTargetType() {
// 创建代理时保留泛型信息
ResolvableType targetType = ResolvableType.forClass(UserRepository.class)
.as(Repository.class);
// 获取目标类型的泛型参数
Class<?> entityType = targetType.getGeneric(0).resolve();
System.out.println("代理目标的实体类型:" + entityType.getName());
}
/**
* 检查类型兼容性(用于AOP切入点匹配)
*/
public void checkTypeCompatibility() {
ResolvableType repositoryType = ResolvableType.forClass(Repository.class);
ResolvableType jpaRepositoryType = ResolvableType.forClass(JpaRepository.class);
ResolvableType userRepositoryType = ResolvableType.forClass(UserRepository.class);
// 检查UserRepository是否实现了Repository
boolean isRepository = repositoryType.isAssignableFrom(userRepositoryType);
System.out.println("UserRepository是Repository的子类型:" + isRepository);
// 检查JpaRepository是否实现了Repository
boolean isJpaRepository = repositoryType.isAssignableFrom(jpaRepositoryType);
System.out.println("JpaRepository是Repository的子类型:" + isJpaRepository);
}
}2.5 场景4:类型转换
java
/**
* 场景:ConversionService需要知道源类型和目标类型的泛型信息
*
* 示例:
* 将 List<String> 转换为 Set<Integer>
* 需要知道:源类型是List,源泛型是String,目标类型是Set,目标泛型是Integer
*/
public class TypeConversionExample {
/**
* 使用ResolvableType进行类型转换
*/
public void convertWithGenerics() {
// 源类型:List<String>
ResolvableType sourceType = ResolvableType.forClassWithGenerics(
List.class, String.class);
// 目标类型:Set<Integer>
ResolvableType targetType = ResolvableType.forClassWithGenerics(
Set.class, Integer.class);
// 执行转换
List<String> source = Arrays.asList("1", "2", "3");
Set<Integer> target = convert(source, sourceType, targetType);
System.out.println("转换结果:" + target);
}
/**
* 泛型转换方法
*/
@SuppressWarnings("unchecked")
private <S, T> T convert(S source, ResolvableType sourceType, ResolvableType targetType) {
// 1. 解析源类型和目标类型
Class<?> sourceClass = sourceType.resolve();
Class<?> targetClass = targetType.resolve();
// 2. 解析泛型参数
Class<?> sourceGeneric = sourceType.getGeneric(0).resolve();
Class<?> targetGeneric = targetType.getGeneric(0).resolve();
// 3. 执行转换逻辑
// ...
return (T) convertInternal(source, sourceGeneric, targetGeneric);
}
private Object convertInternal(Object source, Class<?> sourceGeneric, Class<?> targetGeneric) {
// 具体的转换逻辑
if (source instanceof Collection) {
Collection<?> sourceCollection = (Collection<?>) source;
return sourceCollection.stream()
.map(item -> convertItem(item, targetGeneric))
.collect(Collectors.toSet());
}
return null;
}
@SuppressWarnings("unchecked")
private <T> T convertItem(Object item, Class<T> targetType) {
// 单个元素的转换
if (targetType == Integer.class && item instanceof String) {
return (T) Integer.valueOf((String) item);
}
return (T) item;
}
}2.6 场景5:事件驱动编程
java
/**
* 场景:Spring事件机制中,监听器需要知道事件的具体类型
*
* 示例:
* ApplicationListener<EntityCreatedEvent<User>> listener
* 需要确保只接收User类型的事件
*/
public class EventDrivenExample {
/**
* 泛型事件监听器
*/
public abstract class TypedEventListener<E> implements ApplicationListener<E> {
private final Class<?> eventType;
@SuppressWarnings("unchecked")
public TypedEventListener() {
// 解析泛型参数E的实际类型
ResolvableType resolvableType = ResolvableType.forClass(getClass())
.as(TypedEventListener.class);
this.eventType = resolvableType.getGeneric(0).resolve();
}
@Override
public void onApplicationEvent(E event) {
if (eventType.isInstance(event)) {
handleEvent(event);
}
}
protected abstract void handleEvent(E event);
}
/**
* 具体的事件监听器
*/
@Component
public class UserCreatedListener extends TypedEventListener<EntityCreatedEvent<User>> {
@Override
protected void handleEvent(EntityCreatedEvent<User> event) {
User user = event.getEntity();
System.out.println("用户创建事件:" + user.getName());
}
}
/**
* 泛型事件
*/
public class EntityCreatedEvent<T> extends ApplicationEvent {
private final T entity;
public EntityCreatedEvent(Object source, T entity) {
super(source);
this.entity = entity;
}
public T getEntity() {
return entity;
}
}
}3. 围绕主要场景的封装设计
3.0 封装设计原则
基于对主要使用场景的深度分析,封装设计遵循以下原则:
3.1 封装目标
| 目标 | 问题 | 解决方案 | 效果 |
|---|---|---|---|
| 简化API | ResolvableType API复杂,参数多 | 提供静态工具方法 | 一行代码完成解析 |
| 类型安全 | 返回Class<?>需要强制转换 | 使用泛型方法 | 编译时类型检查 |
| 异常处理 | 反射操作抛出受检异常 | 包装为运行时异常 | 代码更简洁 |
| 缓存优化 | 重复解析相同类型 | 多级缓存机制 | 提升性能 |
| 链式调用 | 嵌套泛型解析繁琐 | 提供链式API | 代码可读性高 |
3.2 封装实现
java
/**
* LinsirType - 类型系统封装
* 基于 Spring ResolvableType 的简化封装
*/
public final class LinsirType {
private LinsirType() {
// 工具类,禁止实例化
}
// ========== 核心解析方法 ==========
/**
* 解析类的泛型参数
*
* 示例:
* class UserService implements Service<User, Long> {}
*
* Class<User> entityClass = LinsirType.resolveGeneric(
* UserService.class, Service.class, 0);
* // 结果:User.class
*
* Class<Long> idClass = LinsirType.resolveGeneric(
* UserService.class, Service.class, 1);
* // 结果:Long.class
*
* @param clazz 要解析的类
* @param genericInterface 泛型接口
* @param index 泛型参数索引
* @return 解析后的Class,如果无法解析返回null
*/
@SuppressWarnings("unchecked")
public static <T> Class<T> resolveGeneric(
Class<?> clazz,
Class<?> genericInterface,
int index) {
Assert.notNull(clazz, "Class must not be null");
Assert.notNull(genericInterface, "Generic interface must not be null");
Assert.isTrue(index >= 0, "Index must be non-negative");
ResolvableType type = ResolvableType.forClass(clazz)
.as(genericInterface);
if (type == ResolvableType.NONE) {
return null;
}
return (Class<T>) type.getGeneric(index).resolve();
}
/**
* 解析类的所有泛型参数
*
* 示例:
* Class<?>[] generics = LinsirType.resolveGenerics(
* UserService.class, Service.class);
* // 结果:[User.class, Long.class]
*
* @param clazz 要解析的类
* @param genericInterface 泛型接口
* @return 泛型参数数组,如果无法解析返回空数组
*/
public static Class<?>[] resolveGenerics(
Class<?> clazz,
Class<?> genericInterface) {
Assert.notNull(clazz, "Class must not be null");
Assert.notNull(genericInterface, "Generic interface must not be null");
ResolvableType type = ResolvableType.forClass(clazz)
.as(genericInterface);
if (type == ResolvableType.NONE || !type.hasGenerics()) {
return new Class[0];
}
ResolvableType[] generics = type.getGenerics();
Class<?>[] result = new Class[generics.length];
for (int i = 0; i < generics.length; i++) {
result[i] = generics[i].resolve();
}
return result;
}
/**
* 解析字段的泛型类型
*
* 示例:
* class Config {
* private List<String> names;
* }
*
* Class<String> elementType = LinsirType.resolveFieldGeneric(
* Config.class, "names", 0);
* // 结果:String.class
*
* @param clazz 声明字段的类
* @param fieldName 字段名
* @param index 泛型参数索引
* @return 解析后的Class
*/
@SuppressWarnings("unchecked")
public static <T> Class<T> resolveFieldGeneric(
Class<?> clazz,
String fieldName,
int index) {
Assert.notNull(clazz, "Class must not be null");
Assert.hasText(fieldName, "Field name must not be empty");
try {
Field field = clazz.getDeclaredField(fieldName);
ResolvableType fieldType = ResolvableType.forField(field);
return (Class<T>) fieldType.getGeneric(index).resolve();
} catch (NoSuchFieldException e) {
throw new LinsirTypeException("Field not found: " + fieldName, e);
}
}
/**
* 解析方法返回类型的泛型
*
* 示例:
* interface Repository<T> {
* List<T> findAll();
* }
*
* Class<User> userClass = LinsirType.resolveReturnTypeGeneric(
* UserRepository.class, "findAll", 0);
* // 结果:User.class
*
* @param clazz 实现类
* @param methodName 方法名
* @param index 泛型参数索引
* @return 解析后的Class
*/
@SuppressWarnings("unchecked")
public static <T> Class<T> resolveReturnTypeGeneric(
Class<?> clazz,
String methodName,
int index) {
Assert.notNull(clazz, "Class must not be null");
Assert.hasText(methodName, "Method name must not be empty");
try {
Method method = findMethod(clazz, methodName);
if (method == null) {
throw new LinsirTypeException("Method not found: " + methodName);
}
ResolvableType returnType = ResolvableType.forMethodReturnType(
method, clazz);
return (Class<T>) returnType.getGeneric(index).resolve();
} catch (SecurityException e) {
throw new LinsirTypeException("Cannot access method: " + methodName, e);
}
}
/**
* 解析方法参数的泛型类型
*
* @param clazz 声明方法的类
* @param methodName 方法名
* @param parameterIndex 参数索引
* @param genericIndex 泛型参数索引
* @return 解析后的Class
*/
@SuppressWarnings("unchecked")
public static <T> Class<T> resolveParameterGeneric(
Class<?> clazz,
String methodName,
int parameterIndex,
int genericIndex) {
Assert.notNull(clazz, "Class must not be null");
Assert.hasText(methodName, "Method name must not be empty");
try {
Method method = findMethod(clazz, methodName);
if (method == null) {
throw new LinsirTypeException("Method not found: " + methodName);
}
ResolvableType paramType = ResolvableType.forMethodParameter(
method, parameterIndex);
return (Class<T>) paramType.getGeneric(genericIndex).resolve();
} catch (SecurityException e) {
throw new LinsirTypeException("Cannot access method: " + methodName, e);
}
}
// ========== 类型检查方法 ==========
/**
* 检查是否为指定类型的子类型
*
* 示例:
* boolean isRepository = LinsirType.isSubtypeOf(
* UserRepository.class, Repository.class);
* // 结果:true
*
* @param clazz 要检查的类
* @param superType 父类型
* @return 是否为子类型
*/
public static boolean isSubtypeOf(Class<?> clazz, Class<?> superType) {
Assert.notNull(clazz, "Class must not be null");
Assert.notNull(superType, "Super type must not be null");
ResolvableType type = ResolvableType.forClass(clazz);
ResolvableType superResolvableType = ResolvableType.forClass(superType);
return superResolvableType.isAssignableFrom(type);
}
/**
* 检查是否实现了指定接口
*
* @param clazz 要检查的类
* @param interfaceType 接口类型
* @return 是否实现了接口
*/
public static boolean implementsInterface(Class<?> clazz, Class<?> interfaceType) {
Assert.notNull(clazz, "Class must not be null");
Assert.notNull(interfaceType, "Interface type must not be null");
Assert.isTrue(interfaceType.isInterface(), "Type must be an interface");
return interfaceType.isAssignableFrom(clazz);
}
/**
* 检查是否为数组类型
*
* @param clazz 要检查的类
* @return 是否为数组
*/
public static boolean isArray(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
return ResolvableType.forClass(clazz).isArray();
}
/**
* 获取数组组件类型
*
* 示例:
* Class<?> componentType = LinsirType.getArrayComponentType(String[].class);
* // 结果:String.class
*
* @param arrayClass 数组类
* @return 组件类型,如果不是数组返回null
*/
@SuppressWarnings("unchecked")
public static <T> Class<T> getArrayComponentType(Class<?> arrayClass) {
Assert.notNull(arrayClass, "Class must not be null");
ResolvableType type = ResolvableType.forClass(arrayClass);
if (!type.isArray()) {
return null;
}
return (Class<T>) type.getComponentType().resolve();
}
// ========== 辅助方法 ==========
/**
* 查找方法(考虑继承)
*/
private static Method findMethod(Class<?> clazz, String methodName) {
Method method = ReflectionUtils.findMethod(clazz, methodName);
if (method != null) {
return method;
}
// 尝试在接口中查找
for (Class<?> iface : clazz.getInterfaces()) {
method = findMethod(iface, methodName);
if (method != null) {
return method;
}
}
// 递归查找父类
if (clazz.getSuperclass() != null) {
return findMethod(clazz.getSuperclass(), methodName);
}
return null;
}
/**
* 获取类的泛型签名信息
*
* @param clazz 要分析的类
* @return 泛型签名字符串
*/
public static String getGenericSignature(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
ResolvableType type = ResolvableType.forClass(clazz);
return type.toString();
}
/**
* 获取父类的泛型类型
*
* @param clazz 要分析的类
* @return 父类型的ResolvableType
*/
public static ResolvableType getSuperType(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
return ResolvableType.forClass(clazz).getSuperType();
}
/**
* 获取类实现的所有接口
*
* @param clazz 要分析的类
* @return 接口类型数组
*/
public static ResolvableType[] getInterfaces(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
return ResolvableType.forClass(clazz).getInterfaces();
}
}
/**
* 类型操作异常
*/
public class LinsirTypeException extends RuntimeException {
public LinsirTypeException(String message) {
super(message);
}
public LinsirTypeException(String message, Throwable cause) {
super(message, cause);
}
}3.3 使用示例
java
/**
* LinsirType 使用示例
*/
public class LinsirTypeExamples {
// ========== 示例类定义 ==========
interface Service<T, ID> {
T findById(ID id);
List<T> findAll();
}
class UserService implements Service<User, Long> {
public User findById(Long id) { return null; }
public List<User> findAll() { return null; }
}
class Config {
private List<String> names;
private Map<String, Integer> settings;
}
// ========== 使用示例 ==========
/**
* 解析类的泛型参数
*/
public void resolveClassGenerics() {
// 解析 UserService 的 Service 接口泛型
Class<User> entityClass = LinsirType.resolveGeneric(
UserService.class, Service.class, 0);
// 结果:User.class
Class<Long> idClass = LinsirType.resolveGeneric(
UserService.class, Service.class, 1);
// 结果:Long.class
// 解析所有泛型
Class<?>[] generics = LinsirType.resolveGenerics(
UserService.class, Service.class);
// 结果:[User.class, Long.class]
}
/**
* 解析字段泛型
*/
public void resolveFieldGenerics() throws NoSuchFieldException {
// 解析 List<String>
Class<String> stringClass = LinsirType.resolveFieldGeneric(
Config.class, "names", 0);
// 结果:String.class
// 解析 Map<String, Integer> 的键
Class<String> keyClass = LinsirType.resolveFieldGeneric(
Config.class, "settings", 0);
// 结果:String.class
// 解析 Map<String, Integer> 的值
Class<Integer> valueClass = LinsirType.resolveFieldGeneric(
Config.class, "settings", 1);
// 结果:Integer.class
}
/**
* 类型检查
*/
public void typeChecking() {
// 检查是否为子类型
boolean isService = LinsirType.isSubtypeOf(
UserService.class, Service.class);
// 结果:true
// 检查是否实现了接口
boolean implementsService = LinsirType.implementsInterface(
UserService.class, Service.class);
// 结果:true
// 检查是否为数组
boolean isArray = LinsirType.isArray(String[].class);
// 结果:true
// 获取数组组件类型
Class<String> componentType = LinsirType.getArrayComponentType(
String[].class);
// 结果:String.class
}
}4. 模块扩展分析
4.0 扩展分析概述
类型系统作为基础能力,在框架各层都有广泛应用。扩展分析从以下维度展开:
| 维度 | 分析内容 | 价值 |
|---|---|---|
| 模块关系 | 与linsir-beans、linsir-context等模块的交互 | 理解类型系统的核心地位 |
| 扩展点设计 | 如何支持自定义类型解析 | 提供框架扩展能力 |
| 性能优化 | 缓存策略、批量解析等 | 提升运行时性能 |
| 跨语言支持 | Kotlin等JVM语言的集成 | 增强框架适用性 |
| 源码演进 | Spring版本迭代中的变化 | 把握设计趋势 |
4.1 与 Spring 其他模块的关系
4.1.1 模块依赖图
4.1.2 调用链路分析
4.2 扩展点设计
java
/**
* 类型解析扩展接口
* 允许自定义类型解析逻辑
*/
public interface TypeResolverExtension {
/**
* 是否支持该类型的解析
*/
boolean supports(Type type);
/**
* 解析类型
*/
ResolvableType resolve(Type type, VariableResolver variableResolver);
}
/**
* 类型解析扩展注册器
*/
public class TypeResolverExtensionRegistry {
private final List<TypeResolverExtension> extensions = new ArrayList<>();
public void registerExtension(TypeResolverExtension extension) {
extensions.add(extension);
}
public ResolvableType resolve(Type type, VariableResolver variableResolver) {
for (TypeResolverExtension extension : extensions) {
if (extension.supports(type)) {
return extension.resolve(type, variableResolver);
}
}
return null;
}
}4.3 性能优化建议
java
/**
* 类型解析性能优化
*/
public class TypeResolutionOptimizer {
/**
* 本地缓存(线程级)
* 减少全局缓存的锁竞争
*/
private static final ThreadLocal<Map<Type, ResolvableType>> localCache =
ThreadLocal.withInitial(HashMap::new);
/**
* 带本地缓存的类型解析
*/
public static ResolvableType resolveWithLocalCache(Type type) {
Map<Type, ResolvableType> cache = localCache.get();
// 先查本地缓存
ResolvableType result = cache.get(type);
if (result != null) {
return result;
}
// 查全局缓存
result = ResolvableType.forType(type);
// 放入本地缓存
cache.put(type, result);
return result;
}
/**
* 批量类型解析
* 减少重复解析开销
*/
public static Map<Type, ResolvableType> resolveBatch(Collection<Type> types) {
Map<Type, ResolvableType> results = new HashMap<>(types.size());
for (Type type : types) {
results.put(type, ResolvableType.forType(type));
}
return results;
}
}4.4 与 Kotlin 的集成
kotlin
/**
* Kotlin 扩展函数
*/
inline fun <reified T> Class<*>.resolveGeneric(
genericInterface: Class<*>,
index: Int
): Class<T>? {
return LinsirType.resolveGeneric(this, genericInterface, index)
}
inline fun <reified T> KClass<*>.resolveGeneric(
genericInterface: KClass<*>,
index: Int
): KClass<T>? {
return LinsirType.resolveGeneric(this.java, genericInterface.java, index)
?.kotlin as? KClass<T>
}
// 使用示例
val entityClass = UserService::class.resolveGeneric<User>(Service::class, 0)4.5 源码演进分析
4.5.1 Spring版本演进
| 版本 | 主要变化 | 影响 |
|---|---|---|
| 3.2 | 引入ResolvableType | 解决泛型擦除问题 |
| 4.0 | 优化缓存机制 | 使用ConcurrentReferenceHashMap |
| 4.2 | 支持泛型数组 | 增强数组类型解析 |
| 5.0 | 支持Reactive类型 | 适配响应式编程 |
| 5.3 | 性能优化 | 减少内存分配 |
| 6.0 | 支持Java 17 | 适配新类型特性 |
4.5.2 设计模式应用
4.6 最佳实践
4.6.1 使用建议
java
/**
* 最佳实践示例
*/
public class TypeSystemBestPractices {
/**
* 实践1:优先使用缓存
* 避免重复解析相同类型
*/
public void useCache() {
// 好的做法:ResolvableType内部已缓存
ResolvableType type1 = ResolvableType.forClass(UserService.class);
ResolvableType type2 = ResolvableType.forClass(UserService.class);
// type1和type2可能是同一实例
}
/**
* 实践2:正确处理NONE
* 检查返回结果是否为NONE
*/
public void handleNone() {
ResolvableType type = ResolvableType.forClass(String.class)
.as(List.class); // String不是List的子类型
if (type == ResolvableType.NONE) {
// 处理类型不匹配的情况
return;
}
// 继续处理
}
/**
* 实践3:避免过度解析
* 一次解析,多次使用
*/
public void avoidOverParsing() {
// 不好的做法:多次解析
Class<?> t1 = ResolvableType.forClass(UserService.class)
.as(Service.class).getGeneric(0).resolve();
Class<?> t2 = ResolvableType.forClass(UserService.class)
.as(Service.class).getGeneric(1).resolve();
// 好的做法:一次解析
ResolvableType serviceType = ResolvableType.forClass(UserService.class)
.as(Service.class);
Class<?> t3 = serviceType.getGeneric(0).resolve();
Class<?> t4 = serviceType.getGeneric(1).resolve();
}
/**
* 实践4:使用封装API
* 简化代码,提高可读性
*/
public void useWrapperApi() {
// 使用LinsirType封装
Class<User> entityClass = LinsirType.resolveGeneric(
UserService.class, Service.class, 0);
// 比直接使用ResolvableType更简洁
}
}4.6.2 常见陷阱
| 陷阱 | 问题描述 | 解决方案 |
|---|---|---|
| 忽略泛型擦除 | 运行时无法获取方法参数泛型 | 使用MethodParameter |
| 缓存泄漏 | 大量类型导致内存溢出 | 使用软引用缓存 |
| 并发问题 | 多线程环境下类型解析异常 | ResolvableType是线程安全的 |
| 类型不匹配 | as()返回NONE未检查 | 始终检查返回值 |
4.7 未来扩展方向
总结
5.1 核心要点回顾
ResolvableType 是 Spring Framework 类型系统的核心,解决了 Java 泛型擦除带来的运行时类型信息缺失问题。
代码结构要点
主要使用场景
| 场景 | 核心API | 使用频率 | 重要性 |
|---|---|---|---|
| 泛型依赖注入 | forClass() + as() + getGeneric() | ⭐⭐⭐⭐⭐ | 核心 |
| 数据绑定 | forField() + getGeneric() | ⭐⭐⭐⭐⭐ | 核心 |
| AOP代理 | forClass() + as() | ⭐⭐⭐ | 重要 |
| 类型转换 | forMethodParameter() + resolve() | ⭐⭐⭐⭐ | 重要 |
| 事件驱动 | forClass() + isAssignableFrom() | ⭐⭐⭐ | 一般 |
| 仓库元数据 | forClass() + as() + getGeneric() | ⭐⭐ | 一般 |
封装设计价值
通过 LinsirType 封装,实现以下目标:
| 目标 | 实现方式 | 效果 |
|---|---|---|
| 简化API | 静态工具方法 | 一行代码完成解析 |
| 类型安全 | 泛型方法 | 编译时类型检查 |
| 异常处理 | 运行时异常包装 | 代码更简洁 |
| 缓存优化 | 多级缓存机制 | 提升性能 |
| 链式调用 | Fluent API设计 | 代码可读性高 |
5.2 核心能力
- 类型解析 - 从 Class、Field、Method 解析泛型信息
- 泛型获取 - 支持多级泛型嵌套解析
- 类型检查 - 支持复杂的类型兼容性检查
- 缓存优化 - 使用软引用缓存提升性能
5.3 使用场景
- 依赖注入 - 解析泛型类型的 Bean 依赖
- 数据绑定 - 将请求参数绑定到泛型对象
- AOP 代理 - 保留代理对象的泛型信息
- 类型转换 - 支持泛型类型的转换
- 事件驱动 - 泛型事件的精确匹配
5.4 封装价值
通过 LinsirType 封装,可以:
- 简化 API,一行代码完成复杂类型解析
- 提供类型安全,编译时检查类型正确性
- 统一异常处理,避免受检异常污染代码
- 提升性能,内置多级缓存机制