Mybatis只有接口没有实现类的原理
Posted bruce128
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis只有接口没有实现类的原理相关的知识,希望对你有一定的参考价值。
一、问题背景
mybaits相对于Ibatis的一大区别就是,不用自己写接口实现类。Ibatis的实现类十几年来做着重复的工作,拼接statementId,然后执行sql。十分没有营养的代码。mybaits干脆不用手工写实现类了,框架帮我们完成了这件事情。
二、实现原理
mybatis使用了动态代理
技术生成实现类。动态代理的具体手段有两种:jdk自带和cglib。
动态代理技术对比 | jdk自带 | cglib |
---|---|---|
是否需要声明接口 | 需要 | 不需要 |
是否需要实现类 | 不需要 | 需要 |
虽然都是生成字节码新类,但是cglib的字节码新类需要继承实现类。对于mybatis只有接口的场景,当然选择jdk自带的动态代理。
三、源码分析
mybatis动态代理两个核心类
org.apache.ibatis.binding.MapperProxy
org.apache.ibatis.binding.MapperProxyFactory
- MapperProxy作用
public class MapperProxy<T> implements InvocationHandler, Serializable
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
... ...
final MapperMethod mapperMethod = cachedMapperMethod(method);
return mapperMethod.execute(sqlSession, args);
这个类实现了代理拦截器方法,也就意味着,新生成的所有代理类的方法都会走这个invoke方法里的逻辑。invoke方法最后一行做了什么呢?
- 拼接statementID
- 执行sql
- 返回结果
这不正是之前写Ibatis接口实现类的时候,天天重复写的代码吗?
- MapperProxyFactory 作用
public class MapperProxyFactory<T>
@SuppressWarnings("unchecked")
protected T newInstance(MapperProxy<T> mapperProxy)
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] mapperInterface , mapperProxy);
public T newInstance(SqlSession sqlSession)
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
MapperProxyFactory是代理工厂类,根据传入的DAO的接口,生成对应实现的动态代理类。每个接口一个动态代理实现类,于是乎,再也不用写Ibatis的那些冗余的代码。
四、结语
mybatis设计的很巧妙,把在ibatis中重复的逻辑用一个动态代理的拦截器进行去重。很高级的duplicate code重构技巧。一个好的架构,可以节省开发同学的时间。
以上是关于Mybatis只有接口没有实现类的原理的主要内容,如果未能解决你的问题,请参考以下文章