深入理解MyBatis核心基础设施,掌握对象操作的本质原理
引言
在使用MyBatis进行开发时,你是否好奇过:
MyBatis如何将ResultSet数据自动映射到Java对象?
它是如何在运行时动态操作对象属性的?
为什么MyBatis能够处理各种复杂的嵌套属性?
一、MyBatis整体架构与反射模块
1.1 反射模块在MyBatis中的位置

从架构图可以看出,MyBatis采用了分层设计,而反射模块(Reflection)位于基础支撑层,是整个框架的核心基础设施。
1.2 反射模块的五大核心职责
✅ 对象属性访问 - 通过反射读写对象属性
✅ 对象实例化 - 动态创建对象实例
✅ 类型解析 - 分析类的类型信息
✅ 元数据获取 - 获取方法、字段、构造器等元数据
✅ 性能优化 - 缓存反射信息,提升性能
1.3 为什么需要反射模块?
场景1:结果映射
ResultSet → 提取数据 → 通过反射设置到Java对象
场景2:参数传递
Java对象 → 通过反射获取属性值 → 设置到PreparedStatement
场景3:对象创建
Mapper返回类型 → 通过反射创建实例 → 填充数据
场景4:元数据解析
XML配置 → 解析类名 → 通过反射获取类信息
没有反射模块,这些操作都需要手工编写大量重复代码!
1.4 Java反射基础回顾
ini
// 获取Class对象
Class<?> clazz = User.class;
// 创建实例
Object obj = clazz.newInstance();
// 获取方法
Method method = clazz.getMethod("setName", String.class);
// 调用方法
method.invoke(obj, "张三");
// 获取字段
Field field = clazz.getDeclaredField("name");
field.setAccessible(true);
field.set(obj, "张三");
二、反射模块架构

2.1 反射模块组成
Reflection(反射模块)
├── ObjectFactory(对象工厂)
├── PropertyTokenizer(属性分词器)
├── PropertyCopier(属性复制器)
├── Reflector(反射器)
├── MetaClass(元数据类)
├── MetaObject(元对象)
└── SystemMetaObject(系统元对象)
2.2 ObjectFactory - 对象工厂
ObjectFactory负责创建对象实例,定义了简单而强大的接口:
typescript
public interface ObjectFactory {
// 创建对象实例
<T> T create(Class<T> type);
// 创建对象实例(带构造参数)
<T> T create(Class<T> type,
Class<?>[] classes,
Object[] values);
// 判断是否为集合类型
<T> boolean isCollection(Class<T> type);
}
默认实现DefaultObjectFactory核心代码:
typescript
public class DefaultObjectFactory implements ObjectFactory {
@Override
public <T> T create(Class<T> type) {
try {
return type.newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Error creating instance of " + type, e);
}
}
@Override
public <T> T create(Class<T> type,
Class<?>[] classes,
Object[] values) {
try {
// 查找匹配的构造器
Constructor<?> constructor =
type.getDeclaredConstructor(classes);
constructor.setAccessible(true);
return (T) constructor.newInstance(values);
} catch (Exception e) {
// 处理异常...
}
return create(type);
}
@Override
public <T> boolean isCollection(Class<T> type) {
return Collection.class.isAssignableFrom(type)
|| type.isArray();
}
}
2.3 PropertyTokenizer - 属性分词器
PropertyTokenizer用于解析复杂的属性表达式,比如user.address.city
核心代码:
ini
public class PropertyTokenizer
implements Iterator<PropertyTokenizer> {
private String fullname; // 完整属性表达式
private String name; // 当前名称
private String indexedName; // 索引名称
private String index; // 索引值
private String children; // 子属性
public PropertyTokenizer(String fullname) {
this.fullname = fullname;
// 解析属性表达式
int delim = fullname.indexOf('.');
if (delim > -1) {
name = fullname.substring(0, delim);
children = fullname.substring(delim + 1);
} else {
name = fullname;
children = null;
}
indexedName = name;
// 解析索引 例如:list[0]
delim = name.indexOf('[');
if (delim > -1) {
index = name.substring(delim + 1,
name.length() - 1);
name = name.substring(0, delim);
}
}
@Override
public boolean hasNext() {
return children != null;
}
@Override
public PropertyTokenizer next() {
return new PropertyTokenizer(children);
}
}
使用示例:
ini
String expression = "user.address.city";
PropertyTokenizer tokenizer =
new PropertyTokenizer(expression);
while (tokenizer.hasNext()) {
System.out.println(
"Current: " + tokenizer.getName());
tokenizer = tokenizer.next();
}
// 输出:
// Current: user
// Current: address
// Current: city
2.4 PropertyCopier - 属性复制器
PropertyCopier用于在对象间复制属性:
scss
public class PropertyCopier {
public void copyProperties(Object source,
Object target) {
// 获取元数据
MetaClass sourceMetaClass =
MetaClass.forClass(source.getClass());
MetaClass targetMetaClass =
MetaClass.forClass(target.getClass());
// 获取源对象的所有属性
String[] getterNames =
sourceMetaClass.getGetterNames();
for (String name : getterNames) {
// 检查目标对象是否有对应的setter
if (targetMetaClass.hasSetter(name)) {
try {
// 复制属性值
Object value = sourceMetaClass
.getGetter(name)
.invoke(source);
targetMetaClass
.getSetter(name)
.invoke(target, value);
} catch (Exception e) {
// 忽略无法复制的属性
}
}
}
}
}
三、对象属性访问

3.1 Reflector - 反射器
Reflector是反射模块的核心类,用于缓存类的反射信息。
核心结构:
swift
public class Reflector {
// 类类型
private final Class<?> type;
// 可读属性映射:属性名 -> getter方法
private final Map<String, Invoker> getMethods
= new HashMap<>();
// 可写属性映射:属性名 -> setter方法
private final Map<String, Invoker> setMethods
= new HashMap<>();
// 属性类型映射
private final Map<String, Class<?>> getTypes
= new HashMap<>();
private final Map<String, Class<?>> setTypes
= new HashMap<>();
// 所有属性名
private final Set<String> properties
= new HashSet<>();
public Reflector(Class<?> clazz) {
this.type = clazz;
addDefaultConstructor(clazz);
addGetMethods(clazz);
addSetMethods(clazz);
addFields(clazz);
}
}
添加getter方法的核心逻辑:
scss
private void addGetMethods(Class<?> clazz) {
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
// 处理getXxx()方法
if (method.getName().startsWith("get")
&& method.getParameterTypes().length == 0) {
String name = method.getName().substring(3);
name = Character.toLowerCase(name.charAt(0))
+ name.substring(1);
addGetMethod(name, method);
}
// 处理isXxx()方法
else if (method.getName().startsWith("is")
&& method.getParameterTypes().length == 0
&& method.getReturnType() == boolean.class) {
String name = method.getName().substring(2);
name = Character.toLowerCase(name.charAt(0))
+ name.substring(1);
addGetMethod(name, method);
}
}
}
3.2 MetaClass - 元数据类
MetaClass对Reflector进行了封装,提供更友好的API:
typescript
public class MetaClass {
private final Reflector reflector;
// 获取属性值
public Object getValue(String name, Object obj) {
try {
Invoker method =
reflector.getGetInvoker(name);
return method.invoke(obj);
} catch (Exception e) {
throw new RuntimeException(
"Error getting property '" + name + "'", e);
}
}
// 设置属性值
public void setValue(String name,
Object obj,
Object value) {
try {
Invoker method =
reflector.getSetInvoker(name);
method.invoke(obj, value);
} catch (Exception e) {
throw new RuntimeException(
"Error setting property '" + name + "'", e);
}
}
// 获取属性类型
public Class<?> getGetterType(String name) {
return reflector.getGetterType(name);
}
// 是否有getter/setter
public boolean hasGetter(String name) {
return reflector.hasGetter(name);
}
public boolean hasSetter(String name) {
return reflector.hasSetter(name);
}
}
3.3 MetaObject - 元对象
MetaObject是元数据的门面类,提供了最友好的API:
typescript
public abstract class MetaObject {
private Object originalObject;
private MetaClass metaClass;
private ObjectWrapper objectWrapper;
// 获取属性值(支持嵌套属性)
public Object getValue(String name) {
PropertyTokenizer prop =
new PropertyTokenizer(name);
if (prop.hasNext()) {
// 处理嵌套属性
return metaClass.getValue(
prop.getName(), originalObject);
} else {
return objectWrapper.get(prop);
}
}
// 设置属性值(支持嵌套属性)
public void setValue(String name, Object value) {
PropertyTokenizer prop =
new PropertyTokenizer(name);
if (prop.hasNext()) {
metaClass.setValue(
prop.getName(), originalObject, value);
} else {
objectWrapper.set(prop, value);
}
}
// 创建MetaObject
public static MetaObject forObject(
Object object,
ObjectFactory objectFactory,
ObjectWrapperFactory objectWrapperFactory) {
if (object == null) {
return SystemMetaObject.NULL_META_OBJECT;
}
// 根据对象类型创建不同的MetaObject
if (object instanceof Map) {
return new MapMetaObject(
(Map) object,
objectFactory,
objectWrapperFactory);
} else if (object instanceof Collection) {
return new CollectionMetaObject(
(Collection) object,
objectFactory,
objectWrapperFactory);
} else {
return new BeanMetaObject(
object,
objectFactory,
objectWrapperFactory);
}
}
}
四、对象实例化

4.1 ObjectFactory创建对象
ini
ObjectFactory objectFactory =
new DefaultObjectFactory();
// 创建简单对象
User user = objectFactory.create(User.class);
// 创建带参对象
Class<?>[] classes = {String.class, String.class};
Object[] values = {"张三", "zhangsan@example.com"};
User user = objectFactory.create(
User.class, classes, values);
// 创建集合
List<User> users =
objectFactory.create(ArrayList.class);
4.2 处理特殊类型
扩展ObjectFactory处理接口和抽象类:
typescript
public class CustomObjectFactory
extends DefaultObjectFactory {
@Override
public <T> T create(Class<T> type) {
// 处理接口类型
if (type.isInterface()) {
if (type.equals(List.class)) {
return (T) new ArrayList<>();
} else if (type.equals(Map.class)) {
return (T) new HashMap<>();
}
throw new RuntimeException(
"Cannot create instance of interface: "
+ type);
}
// 处理抽象类
if (Modifier.isAbstract(type.getModifiers())) {
throw new RuntimeException(
"Cannot create instance of abstract class: "
+ type);
}
return super.create(type);
}
}
4.3 对象包装器 - ObjectWrapper
ObjectWrapper提供统一的属性访问接口:
arduino
public interface ObjectWrapper {
// 获取属性值
Object get(PropertyTokenizer prop);
// 设置属性值
void set(PropertyTokenizer prop, Object value);
// 获取属性类型
Class<?> getSetterType(String name);
// 是否有setter/getter
boolean hasSetter(String name);
boolean hasGetter(String name);
}
BeanWrapper实现示例:
typescript
public class BeanWrapper extends BaseWrapper
implements ObjectWrapper {
private final Object object;
private final MetaClass metaClass;
@Override
public Object get(PropertyTokenizer prop) {
try {
Invoker method = metaClass.getGetInvoker(
prop.getName());
Object value = method.invoke(object);
if (prop.hasNext() && value != null) {
// 递归获取嵌套属性
return MetaObject
.forObject(value, ...)
.getValue(prop.getChildren());
}
return value;
} catch (Throwable t) {
throw new RuntimeException(
"Error getting property '"
+ prop.getName() + "'", t);
}
}
@Override
public void set(PropertyTokenizer prop,
Object value) {
try {
if (prop.hasNext()) {
// 处理嵌套属性
Object child = get(prop);
if (child == null) {
child = instantiatePropertyValue(
prop.getName(),
prop.getChildren());
set(prop, child);
}
MetaObject
.forObject(child, ...)
.setValue(prop.getChildren(), value);
} else {
Invoker method = metaClass.getSetInvoker(
prop.getName());
method.invoke(object, value);
}
} catch (Throwable t) {
throw new RuntimeException(
"Error setting property '"
+ prop.getName() + "'", t);
}
}
}
五、类型解析

5.1 TypeParameterResolver - 泛型解析
typescript
public class TypeParameterResolverImpl
implements TypeParameterResolver {
private final Type type;
@Override
public Type resolveType(Type rawType, Type jniType) {
// 解析泛型类型
if (rawType instanceof Class) {
return resolveClass((Class<?>) rawType);
} else if (rawType instanceof ParameterizedType) {
return resolveParameterizedType(
(ParameterizedType) rawType);
} else if (rawType instanceof GenericArrayType) {
return resolveGenericArrayType(
(GenericArrayType) rawType);
}
return rawType;
}
}
5.2 TypeAliasRegistry - 类型别名
typescript
public class TypeAliasRegistry {
// 别名到类型的映射
private final Map<String, Class<?>> typeAliases
= new HashMap<>();
// 注册类型别名
public void registerAlias(String alias,
Class<?> value) {
if (alias == null) {
throw new TypeException(
"Type alias cannot be null");
}
typeAliases.put(alias, value);
}
// 根据别名解析类型
public Class<?> resolveAlias(String string) {
if (string == null) {
return null;
}
String key = string.toLowerCase(Locale.ENGLISH);
Class<?> value = typeAliases.get(key);
if (value == null) {
try {
return Class.forName(string);
} catch (ClassNotFoundException e) {
throw new TypeException(
"Could not resolve type alias '"
+ string + "'", e);
}
}
return value;
}
}
5.3 TypeHandlerRegistry - 类型处理器
typescript
public class TypeHandlerRegistry {
// 类型到处理器的映射
private final Map<Type, Map<JdbcType, TypeHandler<?>>>
typeHandlerMap = new HashMap<>();
// 获取类型处理器
public <T> TypeHandler<T> getTypeHandler(
Type type,
JdbcType jdbcType) {
Map<JdbcType, TypeHandler<?>> jdbcTypeHandlerMap
= typeHandlerMap.get(type);
if (jdbcTypeHandlerMap != null) {
TypeHandler<?> handler =
jdbcTypeHandlerMap.get(jdbcType);
if (handler != null) {
return (TypeHandler<T>) handler;
}
}
return getTypeHandler(Object.class);
}
}
六、元数据获取

6.1 获取类信息
csharp
public class ClassInfo {
public static void analyze(Class<?> clazz) {
System.out.println("类名: "
+ clazz.getName());
System.out.println("简单名称: "
+ clazz.getSimpleName());
System.out.println("包名: "
+ clazz.getPackage().getName());
System.out.println("父类: "
+ clazz.getSuperclass().getName());
System.out.println("接口: "
+ Arrays.toString(clazz.getInterfaces()));
// 获取修饰符
int modifiers = clazz.getModifiers();
System.out.println("是否为public: "
+ Modifier.isPublic(modifiers));
System.out.println("是否为abstract: "
+ Modifier.isAbstract(modifiers));
}
}
6.2 获取方法信息
typescript
public class MethodInfo {
// 判断是否为getter方法
private static boolean isGetter(Method method) {
String name = method.getName();
return (name.startsWith("get")
&& name.length() > 3
&& method.getParameterTypes().length == 0)
|| (name.startsWith("is")
&& name.length() > 2
&& method.getParameterTypes().length == 0
&& method.getReturnType() == boolean.class);
}
// 判断是否为setter方法
private static boolean isSetter(Method method) {
String name = method.getName();
return name.startsWith("set")
&& name.length() > 3
&& method.getParameterTypes().length == 1
&& method.getReturnType() == void.class;
}
// 获取属性名
private static String getPropertyName(Method method) {
String name = method.getName();
if (name.startsWith("get")
|| name.startsWith("set")) {
name = name.substring(3);
} else if (name.startsWith("is")) {
name = name.substring(2);
}
return Character.toLowerCase(name.charAt(0))
+ name.substring(1);
}
}
6.3 ReflectorFactory - 工厂模式
typescript
public class ReflectorFactory {
// Reflector缓存
private final ConcurrentMap<Class<?>, Reflector>
reflectorMap = new ConcurrentHashMap<>();
// 获取Reflector
public Reflector findForClass(Class<?> type) {
return reflectorMap.computeIfAbsent(type, k -> {
return new Reflector(k);
});
}
// 判断是否已有缓存
public boolean hasReflectorFor(Class<?> type) {
return reflectorMap.containsKey(type);
}
}
七、最佳实践
7.1 性能优化建议
✅缓存反射信息Reflector自动缓存类的反射信息,避免重复解析
✅避免频繁反射尽量使用MetaObject而非直接使用Java反射API
✅使用对象池在高并发场景下复用对象实例
✅延迟加载只在真正需要时才解析元数据
7.2 使用建议
✅ 首选MetaObject提供统一、友好的属性访问接口
✅ 继承BaseWrapper实现自定义的对象包装器时继承BaseWrapper
✅ 扩展ObjectFactory支持特殊类型的实例化需求
✅ 注册类型别名简化XML配置,提升可读性
7.3 常见问题解决
typescript
// 错误原因:属性名不匹配
// User类字段:userName
// getter方法:getName() ❌
// 正确做法:确保符合JavaBean规范
public String getUserName() { ✅
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
MetaObject metaObject = MetaObject.forObject(user, ...);
// 直接访问
Object address = metaObject.getValue("address");
// 嵌套访问
Object city = metaObject.getValue("address.city");
// 带索引的访问
Object item = metaObject.getValue("orders[0].itemName");
// 使用TypeHandlerRegistry处理类型转换
TypeHandlerRegistry registry = new TypeHandlerRegistry();
TypeHandler<String> handler =
registry.getTypeHandler(String.class);
// 设置参数
handler.setParameter(ps, 1, "张三");
// 获取结果
String result = handler.getResult(rs, "name");
八、总结
关键组件
🔹ObjectFactory - 对象工厂,负责创建对象实例
🔹PropertyTokenizer - 属性分词器,解析嵌套属性表达式
🔹 PropertyCopier - 属性复制器,实现对象属性复制
🔹 Reflector - 反射器,缓存类的反射信息
🔹 MetaClass - 元数据类,封装Reflector
🔹 MetaObject - 元对象,提供统一的属性访问接口
设计思想
MyBatis反射模块的设计思想:
javascript
💎 缓存优化 - 缓存反射信息,避免重复解析
💎 封装复杂度 - 封装Java反射API,简化使用
💎 统一接口 - 通过MetaObject提供统一操作接口
💎 扩展性强 - 支持Map、Collection等多种对象类型
💎 性能优先 - 反射信息只解析一次并缓存