[Spinr+MyBatis配置]為什麼可以DAO層只寫介面,不用寫實現類
阿新 • • 發佈:2018-11-02
以下內容來源:https://www.cnblogs.com/soundcode/p/6497291.html,本文只做記錄。
根據網上的一些知識點,講一下原理:
mybatis通過JDK的動態代理方式,在啟動載入配置檔案時,根據配置mapper的xml去生成Dao的實現。
session.getMapper()使用了代理,當呼叫一次此方法,都會產生一個代理class的instance,看看這個代理class的實現.
public class MapperProxy implements InvocationHandler { ... public static <T> T newMapperProxy(Class<T> mapperInterface, SqlSession sqlSession) { ClassLoader classLoader = mapperInterface.getClassLoader(); Class<?>[] interfaces = new Class[]{mapperInterface}; MapperProxy proxy = new MapperProxy(sqlSession); return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (!OBJECT_METHODS.contains(method.getName())) { final Class<?> declaringInterface = findDeclaringInterface(proxy, method); final MapperMethod mapperMethod = new MapperMethod(declaringInterface, method, sqlSession); final Object result = mapperMethod.execute(args); if (result == null && method.getReturnType().isPrimitive()) { throw new BindingException("Mapper method '" + method.getName() + "' (" + method.getDeclaringClass() + ") attempted to return null from a method with a primitive return type (" + method.getReturnType() + ")."); } return result; } return null; }
這裡是用到了JDK的代理Proxy。 newMapperProxy()可以取得實現interfaces 的class的代理類的例項。
當執行interfaces中的方法的時候,會自動執行invoke()方法,其中public Object invoke(Object proxy, Method method, Object[] args)中 method引數就代表你要執行的方法.
MapperMethod類會使用method方法的methodName 和declaringInterface去取 sqlMapxml 取得對應的sql,也就是拿declaringInterface的類全名加上 sql-id..
總結:
這個就是利用JDK的代理類實現的。