阿里面试,问到Mybatis拦截器,3年Java答不上来?

本文详细介绍了Mybatis拦截器的接口定义、拦截位置、多拦截器实现以及拦截器的使用示例,揭示了其在Executor、ParameterHandler、ResultSetHandler等关键节点的工作原理。同时,文章分享了来自网易工程师的实战经验,适合Java后台开发者深入学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mybatis是java后台开发必不可少的DAO工具,开发过程中经常遇到需要扩展框架功能的地方,这时了解拦截器就很有必要了,本文主要介绍拦截器的接口、位置和原理用法等,并给出了简要的示例。

最近整理的Java架构学习视频和大厂项目底层知识点,需要的同学欢迎私信我【资料】发给你~一起学习进步!

一、接口定义

public interface Interceptor {   
   Object intercept(Invocation invocation) throws Throwable;       
   Object plugin(Object target);    
   void setProperties(Properties properties);
}
  • intercept方法用于拦截处调用,业务需要实现自定义逻辑
  • plugin方法用于封装目标对象,通过该方法可以返回一个代理,官方提供了示例:return Plugin.wrap(target, this)
  • setProperties方法可以配置自定义相关属性,即:接口实现对象的参数配置
  •  

二、拦截位置

 

  • Executor是 Mybatis的内部执行器,它负责调用StatementHandler操作数据库,并把结果集通过 ResultSetHandler进行自动映射。
  • StatementHandler是Mybatis封装jdbc执行sql的对象。
  • ParameterHandler是Mybatis实现Sql入参设置的对象,插件可以改变Sql的参数默认设置。
  • ResultSetHandler是Mybatis把ResultSet集合映射成POJO的接口对象,可以对Mybatis的结果集自动映射进行修改。

 

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

三、多拦截器

<property name="plugins">
    <array>
        <ref bean="paginationInterceptorDDB"/>
        <ref bean="rowBoundPaginationInterceptor"/>
    <bean class="com.github.pagehelper.PageInterceptor">
        <property name="properties">
            <value>
                helperDialect=mysql
                reasonable=true
                supportMethodsArguments=true
                params=count=countSql
                autoRuntimeDialect=true
            </value>
        </property>
    </bean>
    <-- OrderBy 一定要在分页插件下面(主要是为了避免 count 也被增加排序) -->
    <bean class="tk.mybatis.orderbyhelper.OrderByHelper"/>
    </array>
</property>

public class InterceptorChain {

  private final List<Interceptor> interceptors = new ArrayList<Interceptor>();

  public Object pluginAll(Object target) {
    for (Interceptor interceptor : interceptors) {
      target = interceptor.plugin(target);
    }
    return target;
  }

  public void addInterceptor(Interceptor interceptor) {
    interceptors.add(interceptor);
  }
  
  public List<Interceptor> getInterceptors() {
    return Collections.unmodifiableList(interceptors);
  }

}

mybatis拦截器主要采用责任链+JDK动态代理的方式,将拦截对象一层层包装成代理对象然后返回注入框架,这样框架使用的时候会一层层剥开,并调用对应的拦截方法。

四、拦截示例

<-- mybatis-config.xml -->
<plugins>
  <plugin interceptor="org.mybatis.example.ExamplePlugin">
    <property name="someProperty" value="100"/>
  </plugin>
</plugins>

// ExamplePlugin.java
@Intercepts({@Signature(
  type= Executor.class,
  method = "update",
  args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
  public Object intercept(Invocation invocation) throws Throwable {
    return invocation.proceed();
  }
  public Object plugin(Object target) {
    return Plugin.wrap(target, this);
  }
  public void setProperties(Properties properties) {
  }
}

来源:网易工程师-肖恒进

有任何问题欢迎留言交流~


整理总结不易,如果觉得这篇文章有意思的话,欢迎转发、收藏,给我一些鼓励~

有想看的内容或者建议,敬请留言!

最近利用空余时间整理了一些精选Java架构学习视频和大厂项目底层知识点,需要的同学欢迎私信我发给你~一起学习进步!有任何问题也欢迎交流~

Java日记本,每日存档超实用的技术干货学习笔记,每天陪你前进一点点~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值