linsir-core 源码深度分析
本文档深入分析 Linsir Framework 的 linsir-core 模块,这是整个框架的基础设施层,基于 Spring Framework 的 spring-core 封装,为其他所有模块提供基础能力支持。
研究流程
研究流程说明
| 阶段 | 主要工作 | 输出产物 | 示例 |
|---|---|---|---|
| 第一阶段 | 研究spring-core项目代码结构 | 包结构图、类关系图 | 包结构全景 |
| 第二阶段 | 形成核心能力矩阵或模块 | 能力矩阵表格 | 核心能力矩阵 |
| 第三阶段 | 基于每个模块深入研究 | 深入研究文档 | typeSystem/index.md |
| 第四阶段 | 封装和扩展详细设计 | 详细设计文档 | 01-type-system-detailed-design.md |
| 第五阶段 | 撰写代码和测试代码 | 源码+测试代码 | LinsirType.java + LinsirTypeTest.java |
| 第六阶段 | 总结代码使用说明 | 使用指南文档 | 03-type-system-usage-guide.md |
模块概述
定位与价值
核心能力矩阵
| 能力 | 核心类 | 解决的问题 | 使用频率 | 学习优先级 |
|---|---|---|---|---|
| 类型系统 | ResolvableType | Java 泛型擦除问题 | ⭐⭐⭐⭐⭐ | 🔴 高 |
| 反射工具 | ReflectionUtils | 反射操作繁琐、异常处理 | ⭐⭐⭐⭐⭐ | 🔴 高 |
| 资源抽象 | Resource/ResourceLoader | 资源访问不统一 | ⭐⭐⭐⭐ | 🟡 中 |
| 类型转换 | ConversionService | 类型转换重复代码 | ⭐⭐⭐⭐ | 🟡 中 |
| 断言工具 | Assert | 参数校验样板代码 | ⭐⭐⭐⭐⭐ | 🔴 高 |
| 环境抽象 | Environment/PropertySource | 配置管理 | ⭐⭐⭐⭐ | 🟡 中 |
| 注解处理 | AnnotationUtils | 注解元数据获取 | ⭐⭐⭐⭐ | 🟡 中 |
| 任务执行 | TaskExecutor | 异步任务执行 | ⭐⭐⭐ | 🟢 低 |
| 字节码操作 | CglibAopProxy | 动态代理 | ⭐⭐⭐ | 🟢 低 |
包结构全景
org.springframework.core
├── core/ # 核心接口和基础类
│ ├── AttributeAccessor # 属性访问器接口
│ ├── DecoratorProxy # 装饰器代理标记
│ ├── InfrastructureProxy # 基础设施代理标记
│ ├── Ordered # 排序接口
│ └── PriorityOrdered # 高优先级排序
├── io/ # 资源IO抽象
│ ├── Resource # 资源接口
│ ├── ResourceLoader # 资源加载器
│ ├── DefaultResourceLoader # 默认实现
│ ├── PathMatchingResourcePatternResolver # 路径匹配
│ └── PropertySourceFactory # 属性源工厂
├── convert/ # 类型转换系统
│ ├── ConversionService # 转换服务接口
│ ├── Converter # 转换器接口
│ ├── GenericConverter # 通用转换器
│ ├── ConverterFactory # 转换器工厂
│ └── support/ # 支持类
├── env/ # 环境抽象
│ ├── Environment # 环境接口
│ ├── PropertySource # 属性源
│ ├── MutablePropertySources # 可变属性源
│ └── Profiles # Profile支持
├── type/ # 类型系统
│ ├── ResolvableType # 可解析类型
│ ├── ClassMetadata # 类元数据
│ ├── AnnotationMetadata # 注解元数据
│ └── filter/ # 类型过滤器
├── annotation/ # 注解处理
│ ├── AnnotationUtils # 注解工具
│ ├── AnnotatedElementUtils # 注解元素工具
│ ├── MergedAnnotations # 合并注解
│ └── AnnotationAttributes # 注解属性
├── task/ # 任务执行
│ ├── TaskExecutor # 任务执行器
│ ├── AsyncTaskExecutor # 异步执行器
│ └── support/ # 支持类
├── util/ # 工具类集合
│ ├── Assert # 断言
│ ├── ClassUtils # 类工具
│ ├── StringUtils # 字符串工具
│ ├── CollectionUtils # 集合工具
│ ├── ObjectUtils # 对象工具
│ ├── ReflectionUtils # 反射工具
│ ├── ConcurrentReferenceHashMap # 并发引用HashMap
│ └── CompositeIterator # 组合迭代器
├── cglib/ # CGLIB字节码操作(内嵌)
├── objenesis/ # Objenesis实例化(内嵌)
└── asm/ # ASM字节码操作(内嵌)核心组件深度分析
1. 类型系统 - ResolvableType
1.1 问题背景:Java 泛型擦除
Java 泛型在编译时会被擦除,运行时无法直接获取泛型参数:
java
// 定义带泛型的类
public class UserService implements BaseService<User> {}
// 运行时尝试获取泛型参数
Type genericInterface = UserService.class.getGenericInterfaces()[0];
System.out.println(genericType);
// 输出: BaseService<User> - 但无法直接获取 User.class
// 传统方式获取泛型参数非常复杂
ParameterizedType paramType = (ParameterizedType) genericInterface;
Type[] actualTypes = paramType.getActualTypeArguments();
// 还需要处理 TypeVariable、WildcardType 等各种情况1.2 ResolvableType 设计目标
1.3 核心架构
1.4 核心实现原理
java
public class ResolvableType implements Serializable {
// ========== 内部状态 ==========
private final Type type; // 原始类型(Type是Java反射的顶层接口)
private final ResolvableType componentType; // 数组组件类型
private final ResolvableType[] generics; // 泛型参数数组
private final Class<?> resolved; // 解析后的Class
private final VariableResolver variableResolver; // 变量解析器(用于解析泛型变量如T)
// 空类型单例
public static final ResolvableType NONE = new ResolvableType(null, null, null, null);
// ========== 工厂方法 ==========
/**
* 从Class创建ResolvableType
* 最简单的方式,无泛型信息
*/
public static ResolvableType forClass(Class<?> clazz) {
return new ResolvableType(clazz);
}
/**
* 从字段创建,解析字段的泛型类型
* 例如:private List<String> names; 会解析出 String
*/
public static ResolvableType forField(Field field) {
Assert.notNull(field, "Field must not be null");
return forType(field.getGenericType(),
new DefaultVariableResolver(field.getDeclaringClass()));
}
/**
* 从方法参数创建
* 用于解析方法参数的泛型类型
*/
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);
}
/**
* 从方法返回类型创建
* 考虑类继承关系中的泛型替换
*/
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));
}
// ========== 核心解析方法 ==========
/**
* 解析为具体Class
* 如果无法解析返回null
*/
public Class<?> resolve() {
if (this.resolved != null) {
return this.resolved;
}
if (this.type == null) {
return null;
}
return resolveClass();
}
/**
* 解析为指定类型的Class
* 如果解析结果不是expectedType的子类,返回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
*/
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];
}
/**
* 将当前类型视为指定类的子类型,解析其泛型
*
* 例如:
* class UserService implements BaseService<User>
* ResolvableType.forClass(UserService.class).as(BaseService.class)
* 返回 BaseService<User> 的 ResolvableType
*/
public ResolvableType as(Class<?> type) {
if (this.resolved == null || type.isAssignableFrom(this.resolved)) {
return this;
}
// 递归查找父类和接口
for (ResolvableType interfaceType : getInterfaces()) {
ResolvableType asType = interfaceType.as(type);
if (asType != NONE) {
return asType;
}
}
return getSuperType().as(type);
}
/**
* 获取父类型的ResolvableType
*/
public ResolvableType getSuperType() {
Class<?> resolved = resolve();
if (resolved == null || resolved.getSuperclass() == null) {
return NONE;
}
Type superType = resolved.getGenericSuperclass();
return forType(superType, asVariableResolver());
}
/**
* 获取所有接口的ResolvableType
*/
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;
}
// ========== 类型检查 ==========
/**
* 检查当前类型是否可以从其他类型赋值
* 支持数组、泛型、通配符等复杂类型检查
*/
public boolean isAssignableFrom(ResolvableType other) {
// 处理数组类型
if (isArray()) {
return other.isArray() &&
getComponentType().isAssignableFrom(other.getComponentType());
}
// 处理泛型类型
if (resolved == null || other.resolved == null) {
return true; // 无法确定时返回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;
}
/**
* 获取数组组件类型
*/
public ResolvableType getComponentType() {
if (this == NONE) {
return NONE;
}
if (this.componentType != null) {
return this.componentType;
}
// 从type解析组件类型
if (this.type instanceof Class) {
Class<?> componentType = ((Class<?>) this.type).getComponentType();
return forClass(componentType);
}
return NONE;
}
// ========== 私有辅助方法 ==========
private Class<?> resolveClass() {
if (this.type instanceof Class) {
return (Class<?>) this.type;
}
if (this.type instanceof ParameterizedType) {
Type rawType = ((ParameterizedType) this.type).getRawType();
if (rawType instanceof Class) {
return (Class<?>) rawType;
}
}
// 处理 TypeVariable、WildcardType 等
if (this.variableResolver != null) {
ResolvableType resolved = this.variableResolver.resolveVariable(
(TypeVariable<?>) this.type);
if (resolved != null) {
return resolved.resolve();
}
}
return null;
}
}1.5 使用场景示例
java
// ===== 场景1: 解析类继承的泛型接口 =====
public interface BaseService<T, ID> {
T findById(ID id);
List<T> findAll();
}
public class UserService implements BaseService<User, Long> {}
// 使用ResolvableType解析
ResolvableType type = ResolvableType.forClass(UserService.class);
ResolvableType baseService = type.as(BaseService.class);
Class<?> entityClass = baseService.getGeneric(0).resolve(); // User.class
Class<?> idClass = baseService.getGeneric(1).resolve(); // Long.class
// ===== 场景2: 解析字段泛型 =====
public class Config {
private List<String> names;
private Map<String, Integer> settings;
private Map<String, List<User>> complexMap;
}
// 解析 List<String>
Field namesField = Config.class.getDeclaredField("names");
ResolvableType namesType = ResolvableType.forField(namesField);
Class<?> elementType = namesType.getGeneric(0).resolve(); // String.class
// 解析 Map<String, Integer>
Field settingsField = Config.class.getDeclaredField("settings");
ResolvableType settingsType = ResolvableType.forField(settingsField);
Class<?> keyType = settingsType.getGeneric(0).resolve(); // String.class
Class<?> valueType = settingsType.getGeneric(1).resolve(); // Integer.class
// 解析嵌套泛型 Map<String, List<User>>
Field complexField = Config.class.getDeclaredField("complexMap");
ResolvableType complexType = ResolvableType.forField(complexField);
ResolvableType listType = complexType.getGeneric(1); // List<User>
Class<?> userClass = listType.getGeneric(0).resolve(); // User.class
// ===== 场景3: 解析方法返回类型 =====
public interface Repository<T> {
List<T> findAll();
Optional<T> findById(Long id);
}
public class UserRepository implements Repository<User> {
@Override
public List<User> findAll() { return null; }
@Override
public Optional<User> findById(Long id) { return null; }
}
// 解析 findAll 的返回类型
Method findAllMethod = UserRepository.class.getMethod("findAll");
ResolvableType returnType = ResolvableType.forMethodReturnType(findAllMethod, UserRepository.class);
Class<?> genericType = returnType.getGeneric(0).resolve(); // User.class
// 解析 findById 的返回类型
Method findByIdMethod = UserRepository.class.getMethod("findById", Long.class);
ResolvableType returnType2 = ResolvableType.forMethodReturnType(findByIdMethod, UserRepository.class);
Class<?> optionalType = returnType2.getGeneric(0).resolve(); // User.class
// ===== 场景4: 解析方法参数类型 =====
public class UserController {
public void saveUsers(List<User> users, Map<String, Object> metadata) {}
}
Method saveMethod = UserController.class.getMethod("saveUsers", List.class, Map.class);
// 第一个参数
ResolvableType param1 = ResolvableType.forMethodParameter(saveMethod, 0);
Class<?> param1Generic = param1.getGeneric(0).resolve(); // User.class
// 第二个参数
ResolvableType param2 = ResolvableType.forMethodParameter(saveMethod, 1);
Class<?> param2Key = param2.getGeneric(0).resolve(); // String.class
Class<?> param2Value = param2.getGeneric(1).resolve(); // Object.class1.6 缓存机制
java
public class ResolvableType implements Serializable {
// 使用ConcurrentReferenceHashMap实现缓存
// 键: Type + ClassLoader, 值: ResolvableType
// 使用软引用,在内存不足时允许GC回收
private static final ConcurrentReferenceHashMap<ResolvableType, ResolvableType>
cache = new ConcurrentReferenceHashMap<>(256);
/**
* 带缓存的工厂方法
* 相同的Type会返回相同的ResolvableType实例
*/
public static ResolvableType forType(Type type, VariableResolver variableResolver) {
if (type == null) {
return NONE;
}
// 构建缓存键(使用type和variableResolver)
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;
}
/**
* 清空缓存
* 在类加载器被回收时调用,防止内存泄漏
*/
public static void clearCache() {
cache.clear();
}
}
/**
* 并发引用HashMap - Spring自定义实现
* 特点:
* 1. 线程安全(使用分段锁)
* 2. 支持软引用/弱引用作为键或值
* 3. 自动清理被GC回收的条目
*/
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> {
private final ReferenceType referenceType; // SOFT 或 WEAK
private final int concurrencyLevel; // 并发级别
public enum ReferenceType {
SOFT, // 软引用 - 内存不足时回收
WEAK // 弱引用 - 下次GC时回收
}
}2. 反射工具 - ReflectionUtils
2.1 设计动机
标准 Java 反射 API 的问题:
- 受检异常泛滥:每次反射操作都要处理
NoSuchMethodException、IllegalAccessException等 - 访问控制限制:无法直接访问私有成员
- 无缓存机制:重复获取方法/字段信息性能差
- 缺少批量操作:无法方便地遍历类层次结构
2.2 核心架构
2.3 核心实现
java
public abstract class ReflectionUtils {
// ========== 缓存 ==========
// 使用方法数组作为值,避免重复反射获取
private static final Map<Class<?>, Method[]> declaredMethodsCache =
new ConcurrentHashMap<>(256);
private static final Map<Class<?>, Field[]> declaredFieldsCache =
new ConcurrentHashMap<>(256);
// 空数组常量
private static final Method[] EMPTY_METHOD_ARRAY = new Method[0];
private static final Field[] EMPTY_FIELD_ARRAY = new Field[0];
// ========== 方法操作 ==========
/**
* 查找方法(递归父类,支持重载)
*
* @param clazz 目标类
* @param name 方法名
* @param paramTypes 参数类型数组(null表示匹配任意参数)
* @return 找到的方法,未找到返回null
*/
public static Method findMethod(Class<?> clazz, String name, Class<?>... paramTypes) {
Assert.notNull(clazz, "Class must not be null");
Assert.notNull(name, "Method name must not be null");
Class<?> searchType = clazz;
while (searchType != null) {
// 先检查当前类的方法
Method[] methods = getDeclaredMethods(searchType, false);
for (Method method : methods) {
if (name.equals(method.getName()) &&
(paramTypes == null || hasSameParams(method, paramTypes))) {
return method;
}
}
// 递归父类
searchType = searchType.getSuperclass();
}
return null;
}
/**
* 查找方法(带返回类型过滤)
*/
public static Method findMethod(Class<?> clazz, String name, Class<?> returnType,
Class<?>... paramTypes) {
Method method = findMethod(clazz, name, paramTypes);
if (method != null && returnType != null && !returnType.isAssignableFrom(method.getReturnType())) {
return null;
}
return method;
}
/**
* 调用方法(自动处理异常,包装为运行时异常)
*
* @param method 要调用的方法
* @param target 目标对象(静态方法可为null)
* @param args 参数数组
* @return 方法返回值
*/
public static Object invokeMethod(Method method, Object target, Object... args) {
try {
return method.invoke(target, args);
} catch (IllegalAccessException ex) {
handleReflectionException(ex);
} catch (InvocationTargetException ex) {
handleInvocationTargetException(ex);
}
throw new IllegalStateException("Should never get here");
}
/**
* 批量处理方法
* 遍历类及其所有父类的所有方法
*
* @param clazz 目标类
* @param callback 处理方法回调
*/
public static void doWithMethods(Class<?> clazz, MethodCallback callback) {
doWithMethods(clazz, callback, null);
}
/**
* 批量处理方法(带过滤器)
*/
public static void doWithMethods(Class<?> clazz, MethodCallback callback,
MethodFilter filter) {
Method[] methods = getDeclaredMethods(clazz, false);
for (Method method : methods) {
if (filter != null && !filter.matches(method)) {
continue;
}
try {
callback.doWith(method);
} catch (IllegalAccessException ex) {
throw new IllegalStateException("Not allowed to access method '" +
method.getName() + "': " + ex);
}
}
// 递归处理父类
if (clazz.getSuperclass() != null && clazz.getSuperclass() != Object.class) {
doWithMethods(clazz.getSuperclass(), callback, filter);
}
// 处理接口(获取默认方法)
for (Class<?> ifc : clazz.getInterfaces()) {
doWithMethods(ifc, callback, filter);
}
}
/**
* 设置方法可访问(处理私有成员)
* 检查访问权限,必要时调用 setAccessible(true)
*/
public static void makeAccessible(Method method) {
if ((!Modifier.isPublic(method.getModifiers()) ||
!Modifier.isPublic(method.getDeclaringClass().getModifiers())) &&
!method.isAccessible()) {
method.setAccessible(true);
}
}
/**
* 获取声明的方法(带缓存)
*
* @param clazz 目标类
* @param defensive 是否返回防御性拷贝
*/
private static Method[] getDeclaredMethods(Class<?> clazz, boolean defensive) {
Assert.notNull(clazz, "Class must not be null");
Method[] result = declaredMethodsCache.get(clazz);
if (result == null) {
try {
result = clazz.getDeclaredMethods();
// 过滤掉桥接方法(Bridge Method)
result = filterBridgeMethods(result);
} catch (Throwable ex) {
// 处理异常类加载器场景
result = EMPTY_METHOD_ARRAY;
}
declaredMethodsCache.put(clazz, result);
}
return defensive ? result.clone() : result;
}
// ========== 字段操作 ==========
/**
* 查找字段(递归父类)
*
* @param clazz 目标类
* @param name 字段名
* @return 找到的字段,未找到返回null
*/
public static Field findField(Class<?> clazz, String name) {
return findField(clazz, name, null);
}
/**
* 查找指定类型的字段
*
* @param clazz 目标类
* @param name 字段名
* @param type 字段类型(null表示任意类型)
* @return 找到的字段
*/
public static Field findField(Class<?> clazz, String name, Class<?> type) {
Assert.notNull(clazz, "Class must not be null");
Assert.hasText(name, "Field name must not be empty");
Class<?> searchType = clazz;
while (searchType != null) {
Field[] fields = getDeclaredFields(searchType);
for (Field field : fields) {
if (name.equals(field.getName()) &&
(type == null || type.equals(field.getType()))) {
return field;
}
}
searchType = searchType.getSuperclass();
}
return null;
}
/**
* 获取字段值
*
* @param field 字段
* @param target 目标对象(静态字段可为null)
* @return 字段值
*/
public static Object getField(Field field, Object target) {
try {
return field.get(target);
} catch (IllegalAccessException ex) {
handleReflectionException(ex);
throw new IllegalStateException("Unexpected reflection exception");
}
}
/**
* 设置字段值
*
* @param field 字段
* @param target 目标对象
* @param value 要设置的值
*/
public static void setField(Field field, Object target, Object value) {
try {
field.set(target, value);
} catch (IllegalAccessException ex) {
handleReflectionException(ex);
}
}
/**
* 批量处理字段
*/
public static void doWithFields(Class<?> clazz, FieldCallback callback,
FieldFilter filter) {
Field[] fields = getDeclaredFields(clazz);
for (Field field : fields) {
if (filter != null && !filter.matches(field)) {
continue;
}
try {
callback.doWith(field);
} catch (IllegalAccessException ex) {
throw new IllegalStateException("Not allowed to access field '" +
field.getName() + "': " + ex);
}
}
// 递归处理父类
if (clazz.getSuperclass() != null && clazz.getSuperclass() != Object.class) {
doWithFields(clazz.getSuperclass(), callback, filter);
}
}
/**
* 设置字段可访问
*/
public static void makeAccessible(Field field) {
if ((!Modifier.isPublic(field.getModifiers()) ||
!Modifier.isPublic(field.getDeclaringClass().getModifiers()) ||
Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) {
field.setAccessible(true);
}
}
/**
* 获取声明的字段(带缓存)
*/
private static Field[] getDeclaredFields(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
Field[] result = declaredFieldsCache.get(clazz);
if (result == null) {
try {
result = clazz.getDeclaredFields();
} catch (Throwable ex) {
result = EMPTY_FIELD_ARRAY;
}
declaredFieldsCache.put(clazz, result);
}
return result;
}
// ========== 异常处理 ==========
/**
* 统一处理反射异常
* 将受检异常转换为运行时异常
*/
public static void handleReflectionException(Exception ex) {
if (ex instanceof NoSuchMethodException) {
throw new IllegalStateException("Method not found: " + ex.getMessage());
}
if (ex instanceof IllegalAccessException) {
throw new IllegalStateException("Could not access method or field: " + ex.getMessage());
}
if (ex instanceof InvocationTargetException) {
handleInvocationTargetException((InvocationTargetException) ex);
}
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
throw new UndeclaredThrowableException(ex);
}
/**
* 处理方法调用目标异常
* 提取实际的业务异常
*/
public static void handleInvocationTargetException(InvocationTargetException ex) {
rethrowRuntimeException(ex.getTargetException());
}
/**
* 重新抛出运行时异常
*/
public static void rethrowRuntimeException(Throwable ex) {
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
if (ex instanceof Error) {
throw (Error) ex;
}
throw new UndeclaredThrowableException(ex);
}
// ========== 回调接口 ==========
@FunctionalInterface
public interface MethodCallback {
void doWith(Method method) throws IllegalArgumentException, IllegalAccessException;
}
@FunctionalInterface
public interface MethodFilter {
boolean matches(Method method);
}
@FunctionalInterface
public interface FieldCallback {
void doWith(Field field) throws IllegalArgumentException, IllegalAccessException;
}
@FunctionalInterface
public interface FieldFilter {
boolean matches(Field field);
}
}2.4 使用示例
java
// ===== 查找并调用私有方法 =====
public class UserService {
private User findByIdInternal(Long id) {
// 私有业务方法
return new User(id, "test");
}
private void validateUser(User user) {
// 私有验证方法
}
}
// 传统反射方式
Method method = UserService.class.getDeclaredMethod("findByIdInternal", Long.class);
method.setAccessible(true);
User user = (User) method.invoke(service, 1L);
// 使用 ReflectionUtils
Method method = ReflectionUtils.findMethod(UserService.class, "findByIdInternal", Long.class);
ReflectionUtils.makeAccessible(method);
User user = (User) ReflectionUtils.invokeMethod(method, service, 1L);
// ===== 批量处理字段(如对象复制) =====
public static void copyFields(Object source, Object target) {
ReflectionUtils.doWithFields(source.getClass(), field -> {
ReflectionUtils.makeAccessible(field);
Object value = ReflectionUtils.getField(field, source);
ReflectionUtils.setField(field, target, value);
});
}
// ===== 查找所有标注了 @Autowired 的字段并注入 =====
ReflectionUtils.doWithFields(service.getClass(), field -> {
if (field.isAnnotationPresent(Autowired.class)) {
ReflectionUtils.makeAccessible(field);
Object dependency = beanFactory.getBean(field.getType());
ReflectionUtils.setField(field, service, dependency);
}
}, field -> field.isAnnotationPresent(Autowired.class));
// ===== 查找所有标注了 @PostConstruct 的方法并调用 =====
ReflectionUtils.doWithMethods(service.getClass(), method -> {
ReflectionUtils.makeAccessible(method);
ReflectionUtils.invokeMethod(method, service);
}, method -> method.isAnnotationPresent(PostConstruct.class));
// ===== 获取所有 getter 方法 =====
List<Method> getters = new ArrayList<>();
ReflectionUtils.doWithMethods(User.class, method -> {
if (method.getName().startsWith("get") &&
method.getParameterCount() == 0 &&
!method.getReturnType().equals(void.class)) {
getters.add(method);
}
});3. 资源抽象 - Resource 体系
3.1 设计目标
统一不同来源资源的访问方式:
3.2 类层次结构
3.3 Resource 接口定义
java
/**
* 资源接口 - 统一访问底层资源
*/
public interface Resource extends InputStreamSource {
/**
* 资源是否存在
*/
boolean exists();
/**
* 资源是否可读
*/
default boolean isReadable() {
return exists();
}
/**
* 资源是否已打开(是否可重复读取)
*/
default boolean isOpen() {
return false;
}
/**
* 是否为文件系统资源
*/
default boolean isFile() {
return false;
}
/**
* 获取资源的URL
*/
URL getURL() throws IOException;
/**
* 获取资源的URI
*/
URI getURI() throws IOException;
/**
* 获取资源的File
*/
File getFile() throws IOException;
/**
* 获取资源的内容长度
*/
long contentLength() throws IOException;
/**
* 获取资源的最后修改时间
*/
long lastModified() throws IOException;
/**
* 基于当前资源创建相对路径资源
*/
Resource createRelative(String relativePath) throws IOException;
/**
* 获取资源文件名
*/
String getFilename();
/**
* 获取资源描述
*/
String getDescription();
}
/**
* 输入流源接口
*/
public interface InputStreamSource {
/**
* 获取输入流
* 每次调用返回新的输入流
*/
InputStream getInputStream() throws IOException;
}3.4 核心实现类
java
/**
* 类路径资源实现
*/
public class ClassPathResource extends AbstractFileResolvingResource {
private final String path; // 类路径
private final ClassLoader classLoader; // 类加载器
private final Class<?> clazz; // 参考类(用于相对路径)
public ClassPathResource(String path) {
this(path, (ClassLoader) null);
}
public ClassPathResource(String path, ClassLoader classLoader) {
Assert.notNull(path, "Path must not be null");
// 去除开头的 /
this.path = StringUtils.cleanPath(path);
this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
this.clazz = null;
}
@Override
public InputStream getInputStream() throws IOException {
InputStream is;
if (this.clazz != null) {
is = this.clazz.getResourceAsStream(this.path);
} else if (this.classLoader != null) {
is = this.classLoader.getResourceAsStream(this.path);
} else {
is = ClassLoader.getSystemResourceAsStream(this.path);
}
if (is == null) {
throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
}
return is;
}
@Override
public URL getURL() throws IOException {
URL url = resolveURL();
if (url == null) {
throw new FileNotFoundException(getDescription() + " cannot be resolved to URL because it does not exist");
}
return url;
}
@Override
public String getDescription() {
StringBuilder builder = new StringBuilder("class path resource [");
String actualPath = this.path;
if (this.clazz != null) {
actualPath = StringUtils.applyRelativePath(
ClassUtils.classPackageAsResourcePath(this.clazz), actualPath);
}
builder.append(actualPath);
builder.append(']');
return builder.toString();
}
}
/**
* 文件系统资源实现
*/
public class FileSystemResource extends AbstractResource implements WritableResource {
private final File file; // 文件对象
private final String path; // 文件路径
public FileSystemResource(File file) {
Assert.notNull(file, "File must not be null");
this.file = file;
this.path = StringUtils.cleanPath(file.getPath());
}
public FileSystemResource(String path) {
Assert.notNull(path, "Path must not be null");
this.file = new File(path);
this.path = StringUtils.cleanPath(path);
}
@Override
public InputStream getInputStream() throws IOException {
try {
return Files.newInputStream(this.file.toPath());
} catch (NoSuchFileException ex) {
throw new FileNotFoundException(ex.getMessage());
}
}
@Override
public OutputStream getOutputStream() throws IOException {
return Files.newOutputStream(this.file.toPath());
}
@Override
public URL getURL() throws IOException {
return this.file.toURI().toURL();
}
@Override
public File getFile() {
return this.file;
}
@Override
public boolean isWritable() {
return this.file.canWrite();
}
@Override
public String getDescription() {
return "file [" + this.file.getAbsolutePath() + "]";
}
}
/**
* URL资源实现
*/
public class UrlResource extends AbstractFileResolvingResource {
private final URI uri; // URI
private final URL url; // URL
private final URL cleanedUrl; // 清理后的URL
public UrlResource(URL url) {
Assert.notNull(url, "URL must not be null");
this.url = url;
this.cleanedUrl = getCleanedUrl(this.url, url.toString());
this.uri = null;
}
@Override
public InputStream getInputStream() throws IOException {
URLConnection con = this.url.openConnection();
ResourceUtils.useCachesIfNecessary(con);
try {
return con.getInputStream();
} catch (IOException ex) {
// 关闭连接后重新抛出异常
if (con instanceof HttpURLConnection) {
((HttpURLConnection) con).disconnect();
}
throw ex;
}
}
@Override
public URL getURL() {
return this.url;
}
@Override
public String getDescription() {
return "URL [" + this.url + "]";
}
}3.5 ResourceLoader 资源加载器
java
/**
* 资源加载器接口
*/
public interface ResourceLoader {
/** 类路径URL前缀 */
String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX; // "classpath:"
/**
* 根据位置加载资源
* 支持:classpath:、file:、http: 等前缀
*/
Resource getResource(String location);
/**
* 获取类加载器
*/
ClassLoader getClassLoader();
}
/**
* 默认资源加载器实现
*/
public class DefaultResourceLoader implements ResourceLoader {
private ClassLoader classLoader; // 类加载器
public DefaultResourceLoader() {
this.classLoader = ClassUtils.getDefaultClassLoader();
}
public DefaultResourceLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public Resource getResource(String location) {
Assert.notNull(location, "Location must not be null");
// 处理 classpath: 前缀
if (location.startsWith(CLASSPATH_URL_PREFIX)) {
return new ClassPathResource(
location.substring(CLASSPATH_URL_PREFIX.length()),
getClassLoader());
}
try {
// 尝试作为 URL 处理
URL url = new URL(location);
return new UrlResource(url);
} catch (MalformedURLException ex) {
// 不是URL,作为类路径资源处理
return new ClassPathResource(location, getClassLoader());
}
}
@Override
public ClassLoader getClassLoader() {
return (this.classLoader != null ? this.classLoader : ClassUtils.getDefaultClassLoader());
}
}
/**
* 路径匹配资源模式解析器
* 支持 Ant 风格的路径模式:classpath*:/*.xml
*/
public class PathMatchingResourcePatternResolver implements ResourcePatternResolver {
private final ResourceLoader resourceLoader; // 资源加载器
public PathMatchingResourcePatternResolver() {
this.resourceLoader = new DefaultResourceLoader();
}
public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
this.resourceLoader = resourceLoader;
}
/**
* 获取资源
*/
@Override
public Resource getResource(String location) {
return this.resourceLoader.getResource(location);
}
/**
* 根据模式获取多个资源
* 支持:classpath*:/*.xml、/WEB-INF/*-context.xml 等
*/
@Override
public Resource[] getResources(String locationPattern) throws IOException {
Assert.notNull(locationPattern, "Location pattern must not be null");
// 处理 classpath*: 前缀(查找所有类路径下的匹配资源)
if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
// 处理通配符路径
if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
return findPathMatchingResources(locationPattern);
}
// 无通配符,查找所有类路径下的同名资源
else {
return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
}
}
// 其他路径模式
else {
int prefixEnd = locationPattern.indexOf(':') + 1;
if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
return findPathMatchingResources(locationPattern);
}
// 单个资源
else {
return new Resource[] {getResourceLoader().getResource(locationPattern)};
}
}
}
/**
* 查找所有类路径下的匹配资源
*/
protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {
// 分解根路径和子模式
String rootDirPath = determineRootDir(locationPattern);
String subPattern = locationPattern.substring(rootDirPath.length());
// 获取根目录下的所有资源
Resource[] rootDirResources = getResources(rootDirPath);
Set<Resource> result = new LinkedHashSet<>(16);
for (Resource rootDirResource : rootDirResources) {
rootDirResource = resolveRootDirResource(rootDirResource);
URL rootDirUrl = rootDirResource.getURL();
// 根据URL类型使用不同的遍历策略
if (rootDirUrl.getProtocol().equals("file")) {
result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
}
else if (rootDirUrl.getProtocol().equals("jar")) {
result.addAll(doFindPathMatchingJarResources(rootDirResource, rootDirUrl, subPattern));
}
}
return result.toArray(new Resource[0]);
}
/**
* 在文件系统中查找匹配的资源
*/
protected Set<Resource> doFindPathMatchingFileResources(Resource rootDirResource, String subPattern)
throws IOException {
File rootDir = rootDirResource.getFile().getAbsoluteFile();
Set<File> matchingFiles = retrieveMatchingFiles(rootDir, subPattern);
Set<Resource> result = new LinkedHashSet<>(matchingFiles.size());
for (File file : matchingFiles) {
result.add(new FileSystemResource(file));
}
return result;
}
}3.6 使用示例
java
// ===== 加载不同来源的资源 =====
ResourceLoader loader = new DefaultResourceLoader();
// 类路径资源
Resource classpathResource = loader.getResource("classpath:application.yml");
InputStream is1 = classpathResource.getInputStream();
// 文件系统资源
Resource fileResource = loader.getResource("file:/etc/config.yml");
// 或
Resource fileResource2 = new FileSystemResource("/etc/config.yml");
// URL资源
Resource urlResource = loader.getResource("http://example.com/data.json");
// ===== 批量加载资源(使用通配符) =====
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
// 加载所有类路径下的 XML 配置文件
Resource[] resources = resolver.getResources("classpath*:/**/*.xml");
for (Resource resource : resources) {
System.out.println("Found: " + resource.getDescription());
}
// 加载指定目录下的所有 properties 文件
Resource[] props = resolver.getResources("classpath:config/*.properties");
// ===== 读取资源内容 =====
// 方式1:使用输入流
Resource resource = loader.getResource("classpath:data.json");
try (InputStream is = resource.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
String content = reader.lines().collect(Collectors.joining("\n"));
}
// 方式2:使用 FileCopyUtils(Spring工具)
Resource resource2 = loader.getResource("classpath:template.txt");
byte[] bytes = FileCopyUtils.copyToByteArray(resource2.getInputStream());
String content2 = new String(bytes, StandardCharsets.UTF_8);
// ===== 检查资源状态 =====
Resource resource3 = loader.getResource("classpath:optional.yml");
if (resource3.exists()) {
// 资源存在,可以读取
long length = resource3.contentLength();
long lastModified = resource3.lastModified();
}
// ===== Spring Boot 中的常见用法 =====
// 加载配置文件
@Value("classpath:banner.txt")
private Resource bannerResource;
// 加载模板
@Value("classpath:templates/email.html")
private Resource emailTemplate;4. 类型转换系统 - ConversionService
4.1 设计目标
解决类型转换的重复代码问题,提供可扩展的转换框架:
4.2 核心接口设计
java
/**
* 简单转换器接口 - 一对一类型转换
* S: 源类型, T: 目标类型
*/
@FunctionalInterface
public interface Converter<S, T> {
/**
* 执行类型转换
* @param source 源对象(不会为null)
* @return 转换后的目标对象(可以为null)
*/
T convert(S source);
}
/**
* 通用转换器接口 - 支持多对多类型转换
*/
public interface GenericConverter {
/**
* 返回支持的转换类型对
*/
Set<ConvertiblePair> getConvertibleTypes();
/**
* 执行转换
* @param source 源对象
* @param sourceType 源类型描述
* @param targetType 目标类型描述
* @return 转换后的对象
*/
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
/**
* 可转换类型对
*/
final class ConvertiblePair {
private final Class<?> sourceType;
private final Class<?> targetType;
public ConvertiblePair(Class<?> sourceType, Class<?> targetType) {
this.sourceType = sourceType;
this.targetType = targetType;
}
public Class<?> getSourceType() { return sourceType; }
public Class<?> getTargetType() { return targetType; }
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (other == null || getClass() != other.getClass()) return false;
ConvertiblePair that = (ConvertiblePair) other;
return sourceType.equals(that.sourceType) && targetType.equals(that.targetType);
}
@Override
public int hashCode() {
return sourceType.hashCode() * 31 + targetType.hashCode();
}
}
}
/**
* 转换器工厂 - 创建特定类型的转换器
* 用于处理目标类型是泛型的情况,如 String -> List<T>
*/
public interface ConverterFactory<S, R> {
/**
* 获取指定目标类型的转换器
* @param targetType 目标类型
* @return 转换器
*/
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}
/**
* 转换服务接口
*/
public interface ConversionService {
/**
* 是否可以转换
*/
boolean canConvert(Class<?> sourceType, Class<?> targetType);
boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
/**
* 执行转换
*/
<T> T convert(Object source, Class<T> targetType);
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}
/**
* 转换器注册接口
*/
public interface ConverterRegistry {
/**
* 添加简单转换器
*/
void addConverter(Converter<?, ?> converter);
/**
* 添加通用转换器
*/
void addConverter(GenericConverter converter);
/**
* 添加转换器工厂
*/
void addConverterFactory(ConverterFactory<?, ?> factory);
/**
* 移除转换器
*/
void removeConvertible(Class<?> sourceType, Class<?> targetType);
}
/**
* 类型描述符 - 包含泛型信息
*/
public class TypeDescriptor implements Serializable {
private final Class<?> type; // 类型
private final ResolvableType resolvableType; // 可解析类型(包含泛型)
private final AnnotatedElementAdapter annotatedElement; // 注解元素
// 工厂方法
public static TypeDescriptor forObject(Object source) {
if (source == null) {
return null;
}
return new TypeDescriptor(source.getClass());
}
public static TypeDescriptor valueOf(Class<?> type) {
return new TypeDescriptor(type);
}
public static TypeDescriptor collection(Class<?> collectionType, TypeDescriptor elementType) {
Assert.notNull(collectionType, "Collection type must not be null");
if (!Collection.class.isAssignableFrom(collectionType)) {
throw new IllegalArgumentException("Collection type must be a Collection");
}
ResolvableType element = (elementType != null ? elementType.resolvableType : null);
return new TypeDescriptor(ResolvableType.forClassWithGenerics(collectionType, element), null, null);
}
// 获取元素类型(用于集合/数组)
public TypeDescriptor getElementTypeDescriptor() {
if (getResolvableType().isArray()) {
return new TypeDescriptor(getResolvableType().getComponentType(), null, null);
}
if (Collection.class.isAssignableFrom(getType())) {
return new TypeDescriptor(getResolvableType().asCollection().getGeneric(0), null, null);
}
return null;
}
// 获取 Map 的 key/value 类型
public TypeDescriptor getMapKeyTypeDescriptor() {
Assert.isTrue(Map.class.isAssignableFrom(getType()), "Type must be a Map");
return new TypeDescriptor(getResolvableType().asMap().getGeneric(0), null, null);
}
public TypeDescriptor getMapValueTypeDescriptor() {
Assert.isTrue(Map.class.isAssignableFrom(getType()), "Type must be a Map");
return new TypeDescriptor(getResolvableType().asMap().getGeneric(1), null, null);
}
}4.3 实现机制
java
/**
* 默认转换服务实现
*/
public class DefaultConversionService implements ConfigurableConversionService {
// 转换器缓存 - 使用ConcurrentHashMap保证线程安全
private final Map<ConvertiblePair, GenericConverter> converters = new ConcurrentHashMap<>(64);
// 转换器缓存 - 缓存查找结果
private final Map<ConverterCacheKey, GenericConverter> converterCache = new ConcurrentReferenceHashMap<>(64);
public DefaultConversionService() {
// 注册默认转换器
addDefaultConverters(this);
}
@Override
public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
Assert.notNull(targetType, "Target type to convert to cannot be null");
return canConvert(sourceType != null ? TypeDescriptor.valueOf(sourceType) : null,
TypeDescriptor.valueOf(targetType));
}
@Override
public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) {
Assert.notNull(targetType, "Target type to convert to cannot be null");
if (sourceType == null) {
return true; // null 可以转换为任意类型
}
GenericConverter converter = getConverter(sourceType, targetType);
return converter != null;
}
@Override
@SuppressWarnings("unchecked")
public <T> T convert(Object source, Class<T> targetType) {
Assert.notNull(targetType, "Target type to convert to cannot be null");
return (T) convert(source, TypeDescriptor.forObject(source), TypeDescriptor.valueOf(targetType));
}
@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
Assert.notNull(targetType, "Target type to convert to cannot be null");
if (source == null) {
// 处理 null 值
return handleNull(sourceType, targetType);
}
Assert.notNull(sourceType, "Source type to convert from cannot be null");
// 查找转换器
GenericConverter converter = getConverter(sourceType, targetType);
if (converter == null) {
throw new ConverterNotFoundException(sourceType, targetType);
}
// 执行转换
return converter.convert(source, sourceType, targetType);
}
/**
* 查找合适的转换器
* 使用缓存优化性能
*/
protected GenericConverter getConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {
ConverterCacheKey key = new ConverterCacheKey(sourceType, targetType);
// 先查缓存
GenericConverter converter = this.converterCache.get(key);
if (converter != null) {
return converter;
}
// 查找转换器
converter = findConverterForPair(sourceType, targetType);
// 放入缓存
if (converter != null) {
this.converterCache.put(key, converter);
}
return converter;
}
/**
* 为类型对查找转换器
*/
private GenericConverter findConverterForPair(TypeDescriptor sourceType, TypeDescriptor targetType) {
// 直接查找
ConvertiblePair pair = new ConvertiblePair(sourceType.getType(), targetType.getType());
GenericConverter converter = this.converters.get(pair);
if (converter != null) {
return converter;
}
// 尝试父类转换器
return findConverterForSuperTypes(sourceType, targetType);
}
/**
* 查找支持父类型的转换器
*/
private GenericConverter findConverterForSuperTypes(TypeDescriptor sourceType, TypeDescriptor targetType) {
// 遍历源类型的父类和接口
for (Class<?> superType : getSuperTypes(sourceType.getType())) {
ConvertiblePair pair = new ConvertiblePair(superType, targetType.getType());
GenericConverter converter = this.converters.get(pair);
if (converter != null) {
return converter;
}
}
return null;
}
// ========== 注册转换器 ==========
@Override
public void addConverter(Converter<?, ?> converter) {
ResolvableType[] typeInfo = getRequiredTypeInfo(converter.getClass(), Converter.class);
if (typeInfo == null) {
throw new IllegalArgumentException("Unable to determine source type and target type");
}
addConverter(new ConverterAdapter(converter, typeInfo[0], typeInfo[1]));
}
@Override
public void addConverter(GenericConverter converter) {
this.converters.add(converter);
invalidateCache();
}
@Override
public void addConverterFactory(ConverterFactory<?, ?> factory) {
ResolvableType[] typeInfo = getRequiredTypeInfo(factory.getClass(), ConverterFactory.class);
if (typeInfo == null) {
throw new IllegalArgumentException("Unable to determine source type and target type");
}
addConverter(new ConverterFactoryAdapter(factory, typeInfo[0], typeInfo[1]));
}
private void invalidateCache() {
this.converterCache.clear();
}
}4.5 使用示例
java
// ===== 创建转换服务 =====
DefaultConversionService conversionService = new DefaultConversionService();
// 添加自定义转换器
conversionService.addConverter(new StringToDateConverter());
conversionService.addConverter(new UserDtoToUserConverter());
// ===== 基本类型转换 =====
Integer num = conversionService.convert("123", Integer.class);
Long longNum = conversionService.convert("456", Long.class);
Boolean flag = conversionService.convert("true", Boolean.class);
// ===== 集合类型转换 =====
List<String> stringList = conversionService.convert("a,b,c", List.class);
Set<Integer> intSet = conversionService.convert(Arrays.asList("1", "2", "3"), Set.class);
// ===== 枚举转换 =====
Status status = conversionService.convert("ACTIVE", Status.class);
// ===== 自定义对象转换 =====
UserDto dto = new UserDto("john", "john@example.com");
User user = conversionService.convert(dto, User.class);
// ===== 在 Spring 中使用 =====
@Service
public class UserService {
@Autowired
private ConversionService conversionService;
public User createUser(String userData) {
// 从 JSON 字符串转换为用户对象
return conversionService.convert(userData, User.class);
}
}封装设计建议
基于以上分析,为 linsir-core 模块设计以下封装策略:
1. 三层架构设计
2. 核心封装原则
| 原则 | 说明 |
|---|---|
| 简化 API | 减少方法参数,提供默认值 |
| 异常处理 | 将受检异常转为运行时异常 |
| 类型安全 | 利用泛型提供编译时类型检查 |
| 链式调用 | 支持 Fluent API 风格 |
| 缓存优化 | 内置缓存机制提升性能 |
3. 具体封装示例
java
// 类型系统封装
public class LinsirType {
public static <T> Class<T> resolveGeneric(Class<?> clazz, Class<?> genericInterface, int index) {
return ResolvableType.forClass(clazz)
.as(genericInterface)
.getGeneric(index)
.resolve();
}
}
// 反射工具封装
public class LinsirReflection {
public static <T> T invokeMethod(Object target, String methodName, Object... args) {
Method method = ReflectionUtils.findMethod(target.getClass(), methodName,
Arrays.stream(args).map(Object::getClass).toArray(Class[]::new));
ReflectionUtils.makeAccessible(method);
return (T) ReflectionUtils.invokeMethod(method, target, args);
}
}
// 资源加载封装
public class LinsirResources {
public static String readAsString(String location) {
Resource resource = new DefaultResourceLoader().getResource(location);
try (InputStream is = resource.getInputStream()) {
return new String(FileCopyUtils.copyToByteArray(is), StandardCharsets.UTF_8);
} catch (IOException e) {
throw new LinsirResourceException("Failed to read resource: " + location, e);
}
}
}总结
linsir-core 模块作为框架的基础设施层,提供了以下核心能力:
- 类型系统 - 解决 Java 泛型擦除问题,支持运行时类型解析
- 反射工具 - 简化反射操作,提供缓存和异常处理
- 资源抽象 - 统一不同来源资源的访问方式
- 类型转换 - 可扩展的类型转换框架
- 工具类 - 断言、字符串、集合等常用工具
- 环境抽象 - 配置管理和 Profile 支持
- 注解处理 - 注解查找、合并、元注解处理
- 任务执行 - 异步任务执行抽象
- 字节码操作 - CGLIB/ASM/Objenesis 支持
这些能力为上层模块(linsir-beans、linsir-context 等)提供了坚实的基础。