1. 程式人生 > >[Spinr+MyBatis配置]為什麼可以DAO層只寫介面,不用寫實現類

[Spinr+MyBatis配置]為什麼可以DAO層只寫介面,不用寫實現類

以下內容來源: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的代理類實現的。