当前位置: 首页 > news >正文

[spring6: ResolvableType TypeDescriptor ConversionService]-类型系统

MethodParameter

MethodParameter 是 Spring 中用于封装一个 MethodConstructor 的参数元信息(如参数索引、嵌套泛型类型、注解等)的辅助类,其子类 SynthesizingMethodParameter 支持对带有属性别名的注解进行合成处理,广泛应用于 Web 和消息端点的参数解析场景。

public class MethodParameter {private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];// 表示方法或构造器对象。Executable 是 Method 或 Constructor 的父类private final Executable executable;// 表示参数的索引位置。-1 表示方法的返回类型,0 表示第一个参数,1 表示第二个参数,以此类推。private final int parameterIndex;// 表示方法或构造器的参数对象@Nullableprivate volatile Parameter parameter;// 表示目标类型的嵌套级别。通常为 1,但如果是嵌套类型(如 List<List<String>>),嵌套级别可以大于 1。// 例如,List<List<String>> 中,1 表示嵌套的 List 类型,2 表示 List 内部的 String 类型。private int nestingLevel;// typeIndexesPerLevel 是一个映射,用于表示 类型的嵌套层级结构。// 它帮助框架准确地解析 多层嵌套的泛型类型,并获取每个层级的 类型索引。// 对于复杂泛型类型的处理和解析,它提供了非常有用的支持。@NullableMap<Integer, Integer> typeIndexesPerLevel;// 方法或构造器所属的类@Nullableprivate volatile Class<?> containingClass;// 方法参数的类型@Nullableprivate volatile Class<?> parameterType;// 方法参数的泛型类型@Nullableprivate volatile Type genericParameterType;// 方法参数上的注解数组@Nullableprivate volatile Annotation[] parameterAnnotations;// 表示用于发现参数名称的 ParameterNameDiscoverer 对象。// 它是一个接口,用于获取方法或构造器的参数名称(尤其在 Java 8 之前,反射不提供参数名称)@Nullableprivate volatile ParameterNameDiscoverer parameterNameDiscoverer;// 方法参数的名称@Nullablevolatile String parameterName;// 表示嵌套方法参数。它用于表示在嵌套类型中进一步递归获取的 MethodParameter 对象。// 通常在处理嵌套泛型类型时,递归地使用此字段来表示更深层次的类型信息。@Nullableprivate volatile MethodParameter nestedMethodParameter;public MethodParameter(Method method, int parameterIndex) {this(method, parameterIndex, 1);}public MethodParameter(Method method, int parameterIndex, int nestingLevel) {Assert.notNull(method, "Method must not be null");this.executable = method;this.parameterIndex = validateIndex(method, parameterIndex);this.nestingLevel = nestingLevel;}public MethodParameter(Constructor<?> constructor, int parameterIndex) {this(constructor, parameterIndex, 1);}public MethodParameter(Constructor<?> constructor, int parameterIndex, int nestingLevel) {Assert.notNull(constructor, "Constructor must not be null");this.executable = constructor;this.parameterIndex = validateIndex(constructor, parameterIndex);this.nestingLevel = nestingLevel;}MethodParameter(Executable executable, int parameterIndex, @Nullable Class<?> containingClass) {Assert.notNull(executable, "Executable must not be null");this.executable = executable;this.parameterIndex = validateIndex(executable, parameterIndex);this.nestingLevel = 1;this.containingClass = containingClass;}// ...
}
public class Application {public void hashMap(Map<String, List<Integer>> map) {};public void methodParameter() throws NoSuchMethodException {// 获取方法Method method = getClass().getDeclaredMethod("hashMap", Map.class);// 创建 MethodParameter 对象,表示方法的第一个参数MethodParameter methodParameter = new MethodParameter(method, 0);// 获取参数的类型Class<?> parameterType = methodParameter.getParameterType();System.out.println("Parameter Type: " + parameterType.getName());  // 输出: java.util.Map// 获取泛型类型(如果有)if (methodParameter.getGenericParameterType() instanceof ParameterizedType) {ParameterizedType genericType = (ParameterizedType) methodParameter.getGenericParameterType();// 获取 Map 的键值对类型Class<?> keyType = (Class<?>) genericType.getActualTypeArguments()[0];System.out.println("Key Type: " + keyType.getName());  // 输出: java.lang.String// 获取 List 的泛型类型if (genericType.getActualTypeArguments()[1] instanceof ParameterizedType) {ParameterizedType listType = (ParameterizedType) genericType.getActualTypeArguments()[1];Class<?> valueType = (Class<?>) listType.getActualTypeArguments()[0];System.out.println("Value Type (List item): " + valueType.getName());  // 输出: java.lang.Integer}}}public static void main(String[] args) throws NoSuchMethodException {Application application = new Application();application.methodParameter();}
}

ResolvableType

ResolvableType 类封装了一个 Java Type,并提供访问父类型、接口和泛型参数的功能,同时能够最终解析为一个 Class 对象。ResolvableType 可以从fieldmethod parametermethod return typeclass中获取。该类的大多数方法也会返回一个 ResolvableType,便于进行类型导航。

@SuppressWarnings("serial")
public class ResolvableType implements Serializable {public static final ResolvableType NONE = new ResolvableType(EmptyType.INSTANCE, null, null, 0);private static final ResolvableType[] EMPTY_TYPES_ARRAY = new ResolvableType[0];private static final ConcurrentReferenceHashMap<ResolvableType, ResolvableType> cache = new ConcurrentReferenceHashMap<>(256);// Interface Type// All Known Subinterfaces:  GenericArrayType, ParameterizedType, TypeVariable<D>, WildcardType// All Known Implementing Classes:  Classprivate final Type type;/*** The component type for an array or {@code null} if the type should be deduced.*/@Nullableprivate final ResolvableType componentType;/*** Optional provider for the type.*/@Nullableprivate final TypeProvider typeProvider;/*** The {@code VariableResolver} to use or {@code null} if no resolver is available.*/@Nullableprivate final VariableResolver variableResolver;@Nullableprivate final Integer hash;@Nullableprivate Class<?> resolved;@Nullableprivate volatile ResolvableType superType;@Nullableprivate volatile ResolvableType[] interfaces;@Nullableprivate volatile ResolvableType[] generics;@Nullableprivate volatile Boolean unresolvableGenerics;// ...
}
public class Application {// 1.  ResolvableType.forFieldprivate HashMap<String, List<Integer>> hashMap;public void forField() throws NoSuchFieldException {// 从字段获取 ResolvableTypeResolvableType resolvableType = ResolvableType.forField(getClass().getDeclaredField("hashMap"));// 获取字段的类型System.out.println(resolvableType.resolve());// 获取该字段的泛型类型ResolvableType genericType = resolvableType.getGeneric(0); // 获取 HashMap 的第一个泛型参数System.out.println(genericType.resolve()); // 输出 StringgenericType = resolvableType.getGeneric(1); // 获取 HashMap 的第二个泛型参数System.out.println(genericType.resolve()); // 输出 List}// 2.  ResolvableType.forMethodParameterpublic void arrayList(List<String> list) {}public void forMethodParameter() throws NoSuchMethodException {// 获取方法参数的 ResolvableTypeMethod method = getClass().getDeclaredMethod("arrayList", List.class);ResolvableType resolvableType = ResolvableType.forMethodParameter(method, 0);// 获取方法参数的类型System.out.println(resolvableType.resolve());// 获取该参数的泛型类型ResolvableType genericType = resolvableType.getGeneric(0);System.out.println(genericType.resolve()); // 输出 String}// 3.  ResolvableType.forMethodReturnTypepublic HashMap<String, List<Integer>> hashMap() {return new HashMap<>();}public void forMethodReturnType() throws NoSuchMethodException {// 获取方法返回类型的 ResolvableTypeMethod method = getClass().getDeclaredMethod("hashMap");ResolvableType resolvableType = ResolvableType.forMethodReturnType(method);// 获取方法返回类型的类型System.out.println(resolvableType.resolve());// 获取返回类型的泛型参数ResolvableType genericType = resolvableType.getGeneric(0); // 获取 HashMap 的第一个泛型参数System.out.println(genericType.resolve()); // 输出 StringgenericType = resolvableType.getGeneric(1); // 获取 HashMap 的第二个泛型参数System.out.println(genericType.resolve()); // 输出 List}// 4.  ResolvableType.forClasspublic void forClass(){// 通过类获取 ResolvableTypeResolvableType resolvableType = ResolvableType.forClass(HashMap.class);// 获取泛型类型ResolvableType genericType = resolvableType.getGeneric(0);System.out.println(genericType.resolve()); // 输出 ObjectgenericType = resolvableType.getGeneric(1);System.out.println(genericType.resolve()); // 输出 Object}public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {Application application = new Application();application.forField();application.forMethodParameter();application.forMethodReturnType();application.forMethodReturnType();}
}
特性MethodParameterResolvableType
主要关注点方法/构造器的参数信息,如类型、名称、注解、泛型等。类、字段、方法、泛型类型的解析,特别是复杂的泛型类型。
使用场景用于方法或构造器参数的反射分析,尤其在 AOP 和注解处理中非常常见。用于处理类型及其泛型参数,解析类的层级结构、父类、接口、泛型等。
支持的操作获取方法/构造器参数的类型、注解、名称、泛型类型等。解析和访问类型的泛型、父类、接口,类型推断等。
嵌套类型支持支持嵌套类型解析,但更多关注于方法参数的索引。可以轻松解析复杂的嵌套泛型类型,如 List<Map<String, Integer>>
类型解析深度主要用于方法参数或构造器参数,不涉及泛型类型的递归深度。支持对类型的递归解析,特别是复杂的泛型类型及其父类关系。
设计目标封装方法/构造器参数的元数据。提供更广泛的类型解析能力,特别是与泛型相关的类型。

Property

Property 类是 Spring 为避免依赖标准 JavaBeans 的 PropertyDescriptor 而设计的轻量级属性描述符。它支持从类中推导出属性名、类型、访问方法(getter/setter)及注解信息,广泛用于类型转换(如 TypeDescriptor)和元数据处理,具备较强的兼容性和便携性,适用于 Android、Java ME 等不支持 java.beans 包的环境。

public final class Property {private static final Map<Property, Annotation[]> annotationCache = new ConcurrentReferenceHashMap<>();// the class type that owns this propertyprivate final Class<?> objectType;// getter@Nullableprivate final Method readMethod;// setter@Nullableprivate final Method writeMethod;// fieldprivate final String name;private final MethodParameter methodParameter;// from field,getter, setter@Nullableprivate Annotation[] annotations;public Property(Class<?> objectType, @Nullable Method readMethod, @Nullable Method writeMethod) {this(objectType, readMethod, writeMethod, null);}public Property(Class<?> objectType, @Nullable Method readMethod, @Nullable Method writeMethod, @Nullable String name) {this.objectType = objectType;this.readMethod = readMethod;this.writeMethod = writeMethod;this.methodParameter = resolveMethodParameter();this.name = (name != null ? name : resolveName());}// ...
}

TypeDescriptor


@SuppressWarnings("serial")
public class TypeDescriptor implements Serializable {// 缓存一些常见类型(如 int, String, Object 等)对应的 TypeDescriptor 实例,提高性能,避免重复创建。private static final Map<Class<?>, TypeDescriptor> commonTypesCache = new HashMap<>(32);private static final Class<?>[] CACHED_COMMON_TYPES = {boolean.class, Boolean.class, byte.class, Byte.class, char.class, Character.class,double.class, Double.class, float.class, Float.class, int.class, Integer.class,long.class, Long.class, short.class, Short.class, String.class, Object.class};static {for (Class<?> preCachedClass : CACHED_COMMON_TYPES) {commonTypesCache.put(preCachedClass, valueOf(preCachedClass));}}public static TypeDescriptor valueOf(@Nullable Class<?> type) {if (type == null) {type = Object.class;}TypeDescriptor desc = commonTypesCache.get(type);return (desc != null ? desc : new TypeDescriptor(ResolvableType.forClass(type), null, null));}// Java 反射的基础 Class 对象private final Class<?> type;// Spring 封装类型,可获取泛型、数组、嵌套信息private final ResolvableType resolvableType;// 提供注解信息的惰性工厂private final AnnotatedElementSupplier annotatedElementSupplier;// 真正持有注解信息的适配器,实现 AnnotatedElement 接口@Nullableprivate volatile AnnotatedElementAdapter annotatedElement;public TypeDescriptor(MethodParameter methodParameter) {this.resolvableType = ResolvableType.forMethodParameter(methodParameter);this.type = this.resolvableType.resolve(methodParameter.getNestedParameterType());this.annotatedElementSupplier = () -> AnnotatedElementAdapter.from(methodParameter.getParameterIndex() == -1 ?methodParameter.getMethodAnnotations() : methodParameter.getParameterAnnotations());}public TypeDescriptor(Field field) {this.resolvableType = ResolvableType.forField(field);this.type = this.resolvableType.resolve(field.getType());this.annotatedElementSupplier = () -> AnnotatedElementAdapter.from(field.getAnnotations());}public TypeDescriptor(Property property) {Assert.notNull(property, "Property must not be null");this.resolvableType = ResolvableType.forMethodParameter(property.getMethodParameter());this.type = this.resolvableType.resolve(property.getType());this.annotatedElementSupplier = () -> AnnotatedElementAdapter.from(property.getAnnotations());}public TypeDescriptor(ResolvableType resolvableType, @Nullable Class<?> type, @Nullable Annotation[] annotations) {this.resolvableType = resolvableType;this.type = (type != null ? type : resolvableType.toClass());this.annotatedElementSupplier = () -> AnnotatedElementAdapter.from(annotations);}private AnnotatedElementAdapter getAnnotatedElement() {AnnotatedElementAdapter annotatedElement = this.annotatedElement;if (annotatedElement == null) {annotatedElement = this.annotatedElementSupplier.get();this.annotatedElement = annotatedElement;}return annotatedElement;}/*** 一个适配器类,用于将 {@code TypeDescriptor} 中的注解以 {@link AnnotatedElement} 形式暴露出来,* 特别是为了让它可以与 {@link AnnotatedElementUtils} 一起使用。** @see AnnotatedElementUtils#isAnnotated(AnnotatedElement, Class)* 注:这个工具方法用于判断某个元素上是否标注了某个注解(包括合成注解)。** @see AnnotatedElementUtils#getMergedAnnotation(AnnotatedElement, Class)* 注:这个工具方法用于获取某个元素上的注解(支持继承、合并、组合注解等 Spring 特性)。*/private static final class AnnotatedElementAdapter implements AnnotatedElement, Serializable {private static final AnnotatedElementAdapter EMPTY = new AnnotatedElementAdapter(new Annotation[0]);private final Annotation[] annotations;private AnnotatedElementAdapter(Annotation[] annotations) {this.annotations = annotations;}private static AnnotatedElementAdapter from(@Nullable Annotation[] annotations) {if (annotations == null || annotations.length == 0) {return EMPTY;}return new AnnotatedElementAdapter(annotations);}// ...}private interface AnnotatedElementSupplier extends Supplier<AnnotatedElementAdapter>, Serializable {}
}

ConversionService

ConversionService 是一个用于判断和执行类型转换的核心接口,支持简单和复杂类型的安全转换。

public interface ConversionService {// 判断是否可以将 sourceType 类型的对象转换成 targetType 类型boolean canConvert(@Nullable Class<?> sourceType, Class<?> targetType);// 与上面的方法类似,但使用更丰富的 TypeDescriptor 传递类型上下文信息(例如属性、注解等)boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType);// 将源对象转换为指定的目标类型@Nullable<T> T convert(@Nullable Object source, Class<T> targetType);// 默认实现,先构造源对象的 TypeDescriptor,再调用三参的 convert 方法。@Nullabledefault Object convert(@Nullable Object source, TypeDescriptor targetType) {return convert(source, TypeDescriptor.forObject(source), targetType);}// 最完整的转换方法,带有源类型和目标类型的上下文信息。@NullableObject convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType);}

ConfigurableConversionService

ConfigurableConversionService 是 Spring 类型转换系统中最重要的可配置接口,它整合了类型转换的运行能力和配置能力,是构建 GenericConversionServiceFormattingConversionService 的基础接口,广泛应用于 Spring Boot、Spring MVC、Spring Data 等模块中的数据绑定与自动类型转换。

public interface ConfigurableConversionService extends ConversionService, ConverterRegistry {}

GenericConversionService

GenericConversionService 是 Spring 类型转换体系的底层核心类,它通过支持 Converter, ConverterFactory, GenericConverter 接口,实现了从简单类型到复杂泛型结构的全面类型转换能力,是 Spring Boot、Spring Data、Spring Security 等模块实现自动类型绑定的关键支撑组件。

public interface ConverterRegistry {void addConverter(Converter<?, ?> converter);<S, T> void addConverter(Class<S> sourceType, Class<T> targetType, Converter<? super S, ? extends T> converter);void addConverter(GenericConverter converter);void addConverterFactory(ConverterFactory<?, ?> factory);void removeConvertible(Class<?> sourceType, Class<?> targetType);
}

FormattingConversionService

FormattingConversionService 是 Spring 框架中集成了类型转换与字段格式化的统一服务类,它继承自 GenericConversionService 并实现了 FormatterRegistryEmbeddedValueResolverAware 接口,是 Spring MVC、Spring Boot 数据绑定和国际化格式化的核心支撑组件。

public interface FormatterRegistry extends ConverterRegistry {void addPrinter(Printer<?> printer);void addParser(Parser<?> parser);void addFormatter(Formatter<?> formatter);void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter);void addFormatterForFieldType(Class<?> fieldType, Printer<?> printer, Parser<?> parser);void addFormatterForFieldAnnotation(AnnotationFormatterFactory<? extends Annotation> annotationFormatterFactory);
}
http://www.dtcms.com/a/279071.html

相关文章:

  • [笔记] 动态 SQL 查询技术解析:构建灵活高效的企业级数据访问层
  • 131. Java 泛型 - 目标类型与泛型推断
  • VUE3 添加长按手势
  • Nacos 技术研究文档(基于 Nacos 3)
  • 国内MCP服务器搜索引擎有哪些?MCP导航站平台推荐
  • Docker配置国内镜像源
  • SpringBoot整合MongoDB
  • 链表算法之【获取链表开始入环的节点】
  • Codeforces Round 1019 (Div. 2) A-D
  • Windows下安装nvm管理多个版本的node.js
  • 在项目中集成开源的表单设计器FcDesigner源码
  • 「源力觉醒 创作者计划」_文心开源模型(ERNIE-4.5-VL-28B-A3B-PT)使用心得
  • linux系统下Ollama 模型下载出现 “no space left on device” 错误(非Docker)怎么删缓存/没下完的模型?
  • Docker入门基础
  • Vue+axios
  • Cadence操作说明
  • STM32固件升级设计——SD卡升级固件
  • 论文阅读:WildGS-SLAM:Monocular Gaussian Splatting SLAM in Dynamic Environments
  • 如何在 React + TypeScript 中实现 JSON 格式化功能
  • 【React Natve】NetworkError 和 TouchableOpacity 组件
  • MySQL的可重复读隔离级别实现原理分析
  • 银河麒麟KYSEC安全机制详解
  • 在echarts中legend中设置rich中第二项的宽度不起作用的处理方案。
  • PyTorch张量(Tensor)创建的方式汇总详解和代码示例
  • 鸿蒙Next开发,配置Navigation的Route
  • 26-计组-多处理器
  • HCIA认证核心知识体系全解析
  • OpenCV计算机视觉实战(15)——霍夫变换详解
  • Mars3d的走廊只能在一个平面的无法折叠的解决方案
  • UNet 改进(36):引入ELAN-FR模块(通道注意力+空间注意力)