Skip to content

MyBatis 架构与插件机制

一、整体架构(三层)

职责
接口层对外 API:SqlSession / Mapper 接口
数据处理层SQL 查找、解析、执行、结果映射(四大组件所在层)
框架支撑层连接管理、事务、配置加载、缓存

二、四大核心组件(插件拦截点)

MyBatis 对以下四个对象提供了拦截/扩展机制,插件本质就是拦截器,增强靠动态代理实现——四大对象在创建时返回的其实都是被层层代理后的对象:

组件职责可拦截方法
Executor增删改查、事务提交/回滚update / query / commit / rollback
StatementHandlerSQL 语法构建prepare / parameterize / batch / query
ParameterHandler参数处理getParameterObject / setParameters
ResultSetHandler结果集处理handleResultSets / handleOutputParameters

三、插件原理

  1. 四大对象创建时不直接返回,而是经过 interceptorChain.pluginAll(target)
  2. 取出所有 Interceptor,逐个调用 interceptor.plugin(target),返回被包装(代理)后的对象;
  3. 代理拦截到四大对象的每次调用,织入增强逻辑。
  • interceptorChain 在 MyBatis 初始化时创建,持有全部拦截器;
  • 最终 target 是"重重代理"后的对象。

四、自定义插件(示例)

java
@Intercepts({
  @Signature(type = StatementHandler.class,
             method = "prepare",
             args = {Connection.class, Integer.class})
})
public class MyPlugin implements Interceptor {
  @Override public Object intercept(Invocation invocation) throws Throwable {
    System.out.println("对方法进行了增强");
    return invocation.proceed();   // 原方法执行
  }
  @Override public Object plugin(Object target) {
    return Plugin.wrap(target, this); // 生成代理,纳入拦截器链
  }
  @Override public void setProperties(Properties properties) {
    System.out.println("配置参数:" + properties);
  }
}

XML 注册(注意 <plugins> 标签顺序):

xml
<plugins>
  <plugin interceptor="com.wy.plugin.MyPlugin">
    <property name="name" value="tom"/>
  </plugin>
</plugins>

方法执行顺序setProperties()plugin()intercept()

常见误解

  • "插件能拦截任意类" —— 错,只能拦截四大组件公布的指定方法。
  • "plugin() 里要自己写 JDK/CGLIB 代理" —— 错,调 Plugin.wrap(target, this) 即可(MyBatis 已封装)。
  • "四大对象是原始对象" —— 错,经过拦截器链后它们都是代理对象。

关联

最近更新