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

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日记本,每日存档超实用的技术干货学习笔记,每天陪你前进一点点~

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容