深入探索MyBatis的动态代理模式
public class MyBatisMapperProxy<T> implements InvocationHandler {
private final SqlSession sqlSession;
private final Class<T> mapperInterface;
private final Map<Method, MapperMethod> methodCache;
public MyBatisMapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {
this.sqlSession = sqlSession;
this.mapperInterface = mapperInterface;
this.methodCache = methodCache;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class.equals(method.getDeclaringClass())) {
try {
// 处理 Object 中定义的方法,例如 hashCode(), equals() 等
return method.invoke(this, args);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
// 使用 MapperMethod 来执行具体的数据库操作
final MapperMethod mapperMethod = cachedMapperMethod(method);
return mapperMethod.execute(sqlSession, args);
}
private MapperMethod cachedMapperMethod(Method method) {
MapperMethod mapperMethod = methodCache.get(method);
if (mapperMethod == null) {
mapperMethod = new MapperMethod(mapperInterface, method);
methodCache.put(method, mapperMethod);
}
return mapperMethod;
}
}
这个代码示例提供了一个简化版本的 MyBatisMapperProxy
类,它实现了 InvocationHandler
接口。在 invoke
方法中,它会根据传入的方法来创建或者获取 MapperMethod
对象,并使用这个 MapperMethod
来执行具体的数据库操作。这个类模拟了 MyBatis 是如何利用动态代理来简化接口的使用,并降低与具体数据库操作的耦合度。
评论已关闭