mybatis拦截器执行顺序配置_java拦截器使用详解

mybatis拦截器执行顺序配置_java拦截器使用详解最近项目用上了mybatis,但是想像hibernate那样能打印sql,于是写了个基于mybatis拦截器的sql打印,参考这个https://blog.22xcode.com/post/78然后,碰到了问题,拦截器会重复输出一句sql排查下,项目里跟mybatis有关的就只有pagehelper了,猜测可能是pagehelper为了分页再发了一条算总数count的sql,而打印sql的拦截器没有获取到count查询的完整sql,所以看上去发了两遍一样的sql网上找了下拦截器的资料,

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

最近项目用上了mybatis, 但是想像hibernate那样能打印sql, 于是写了个基于mybatis拦截器的sql打印, 参考这个https://blog.22xcode.com/post/78

然后, 碰到了问题, 拦截器会重复输出一句sql

mybatis sql: SELECT id, name FROM user

mybatis sql: SELECT id, name FROM user

排查下, 项目里跟mybatis有关的就只有pagehelper了, 猜测可能是pagehelper 为了分页再发了一条算总数count的sql, 而打印sql的拦截器没有获取到count查询的完整sql, 所以看上去发了两遍一样的sql

网上找了下拦截器的资料, 发现基本都是这个样子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Th2xecl-1656070640683)(/storage/thumbnails/_signature/3PUPLE2S14QE5OG0JJL7RED3FL.png)]

大概意思就是后定义/加载的拦截器会先执行.

于是更改配置, 将sql打印拦截器在pagehelper的拦截器之后执行

	@Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;
    
 	/**
     * 在分页拦截器后加载
     */
    @Autowired
    PageHelperAutoConfiguration pageHelperAutoConfiguration;

    @PostConstruct
    public void registerInterceptor() {
        if (enableSqlLog) {
            MybatisSqlLogInterceptor interceptor = new MybatisSqlLogInterceptor();
            for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
                Configuration configuration = sqlSessionFactory.getConfiguration();
                if (!containsInterceptor(configuration, interceptor)) {
                    configuration.addInterceptor(interceptor);
                }
            }
            log.warn("[mybatis sql log]已启用, 请检查当前是否为开发环境");
        } else {
            log.info("[mybatis sql log]已禁用");
        }
    }

其实也试了下@AutoConfigureAfter, 但是发现不起作用, 后续再琢磨下吧.

配置完成, 再次执行查询, sql只打印一次, 说明sql打印拦截器在分页拦截器之前被调用, 完成

但是为什么先加载的拦截器反而后执行, 网上好像没啥资料, 那就只能自己翻翻源码了.

debug看了下, 找到了这个类

package org.apache.ibatis.plugin;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class InterceptorChain {

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

  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);
  }

}

InterceptorChain顾名思义, 拦截链, 可以看到项目定义的拦截器都在InterceptorChain内用ArrayList存储起来

核心是这个InterceptorChain#pluginAll这个方法

解析下

pluginAll方法中, 遍历interceptors, 为目标对象创建代理.

即, 在这一步, 先加载的拦截器会优先被遍历, 会优先对目标对象进行代理,

后加载的拦截器, 在原有的代理之上再进行代理, 一层包一层, 类似洋葱.

当方法被调用时, 会先执行最外层的代理方法.

所以, 先加载到的拦截器, 反而是最后执行.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196611.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ubuntu16安装中文输入法「建议收藏」

    ubuntu16安装中文输入法「建议收藏」参考自:https://jingyan.baidu.com/article/bad08e1ef4b2f109c85121b7.html原材料:ubuntu16步骤:1.在桌面的最左边选择设置(SystemSettings)2.在设置中选择LanguageSupport3.在弹出的窗口选择Install/RemoveLanguages…4.选择Ch…

    2022年9月26日
    2
  • (详细图解)VS2017安装教程

    (详细图解)VS2017安装教程VS2017版本同15版一样,细分为三个版本,分别是:社区版(Community):免费提供给单个开发人员,给予初学者及大部分程序员支持,可以无任何经济负担、合法地使用。 企业版:为正规企业量身定做,能够提供点对点的解决方案,充分满足企业的需求。企业版官方售价2999美元/年或者250美元/月。 专业版:适用于专业用户或者小团体。虽没有企业版全面的功能,但相比于免费的社区版,…

    2022年4月28日
    58
  • qnap系统安装_snailsvn安装配置教程

    qnap系统安装_snailsvn安装配置教程QNAP安装subversion服务器背景安装1.安装Entware2.安装Subversion配置1.创建仓库2.配置仓库启动svn1.杀掉已有的svn进程2.启动)背景买了一台QNAPTS-453Bmini。是x86的机器,性能强大,最高能装16G内存。某日偶然网上发现有人做svn服务器,于是打算试试。为啥不用Gitlab呢。因为发现Container的网络ip…

    2022年10月17日
    2
  • 向量与矩阵范数_矩阵范数与谱半径的关系

    向量与矩阵范数_矩阵范数与谱半径的关系范数(norm),是具有“长度”概念的函数。在线性代数、泛函分析及相关的数学领域,范函是一个函数,其为矢量空间内的所有矢量赋予非零的正长度或大小。半范数反而可以为非零的矢量赋予零长度。举一个简单的例子,在二维的欧氏几何空间R就可定义欧氏范数。在这个矢量空间中的元素常常在笛卡儿坐标系统中被画成一个从原点出发的带有箭头的有向线段。每一个矢量的欧氏范数就是有向线段的长度。其中定义范数的矢量空间就是赋范矢

    2022年9月19日
    2
  • js判断当前操作系统

    js判断当前操作系统

    2021年9月11日
    64
  • 手机的尺寸、分辨率、像素密度的关系「建议收藏」

    手机的尺寸、分辨率、像素密度的关系「建议收藏」前言一直以来,对手机屏幕尺寸、分辨率、像素和像素密度之间对关系摸不到头脑,今天就借此机会,学习记录一下啦。屏幕(主屏)尺寸是什么,怎么算?平时我们买手机,都有尺寸多大,比如苹果6s是5英寸的,华为p8是5.2英寸的,那么这个数字是怎么来的呢?开始以为是屏幕的面积大小,后来通过查询资料才知道,英寸是长度大小,不是面积单位,所以当然不是屏幕的面积咯。其实手机的尺寸其实代表手机屏幕的对角线长度。英…

    2022年5月22日
    69

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号