天天看點

Mybatis 插件原理

Mybatis是我們平時常用的ORM架構,它很靈活,在靈活的基礎上,我們還可以開發一些Mybatis的插件來實作自己想要的功能。

一起來看下Mybatis插件開發的原理

預備知識

  • JDK的動态代理 Proxy,InvocationHandler
  • 了解Mybatis的基本使用

分析

  1. Mybatis的Configuration對象,存儲了mybatis的配置資訊,在内部多個地方都可以看到Configuration的影子,這是一個非常重要的對象,在追蹤源碼的時候可以看到Mybatis插件生效的地方。
    Mybatis 插件原理
    image.png

通過Configration對象,我們看出可以攔截的對象有

  • ResultSetHandler
  • Executor
  • StatementHandler
  • ParameterHandler
  1. 我們看下interceptorChain.pluginAll的内容。
    Mybatis 插件原理
  1. 再看下Interceptor接口的内容
public interface Interceptor {
  // 
  Object intercept(Invocation invocation) throws Throwable;

  Object plugin(Object target);

  void setProperties(Properties properties);
}

// 攔截器的Invocation參數,内部可以封裝了target,method, args.
public class Invocation {
  private final Object target;
  private final Method method;
  private final Object[] args;

  public Invocation(Object target, Method method, Object[] args) {
    this.target = target;
    this.method = method;
    this.args = args;
  }
  ...
  public Object proceed() throws InvocationTargetException, IllegalAccessException {
    return method.invoke(target, args);
  }

}

           
  1. 插件的用法,一般的使用方式為
Mybatis 插件原理
  1. Plugin.wrap内部實作,利用JDK的Proxy實作,參考 Java使用Porxy和InvocationHandler實作動态代理

invoke方法中,内部interceptor.intercept(new Invocation(target,method,args))。可以照應開始的Interceptor的接口。

Mybatis 插件原理
  1. Plugin類内部實作了很多有用的工具方法,Interceptor借助Plugin來實作,其内部的方法可以多看一下。

最後

插件的内部實作,看Mybatis的源碼就明白怎麼回事,其餘的再自己内部追蹤下。

參考