解决 spring boot 在使用 pagehelper-spring-boot-starter 后 无法使用 自定义拦截器的问题

spring boot  已经使用了自动分页插件 pagehelper-spring-boot-starter ,但是在自定义mybatis 拦截器的时候,并不能生效,原因就是,pagehelper 拦截器,进行拦截处理后,没有调用之后的拦截器,直接返回了自己的执行结果,导致之后的拦截器没有调用.

下面贴出我的代码,可以执行拦截器

 

添加文件:

MyBatisConfig.java 

需要注意,添加了 

@AutoConfigureAfter(PageHelperAutoConfiguration.class)
package com.school.oauth.config;


import com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration;
import com.school.oauth.common.spring.mybatis.MyBatisInterceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.List;

@Configuration
@AutoConfigureAfter(PageHelperAutoConfiguration.class)
public class MyBatisConfig {
    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;

    @PostConstruct
    public void addMyInterceptor() {
        MyBatisInterceptor e = new MyBatisInterceptor();
        for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
            sqlSessionFactory.getConfiguration().addInterceptor(e);
        }
    }
}
添加文件:MyBatisInterceptor.java
package com.school.oauth.common.spring.mybatis;



import com.school.oauth.aop.HttpAspect;
import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandlerRegistry;
import java.text.DateFormat;
import java.util.*;
import java.util.regex.Matcher;

@Intercepts({
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class,
                Object.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class,
                Object.class, RowBounds.class, ResultHandler.class})})
@SuppressWarnings({"unchecked", "rawtypes"})
public class MyBatisInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        try
        {
            // 获取xml中的一个select/update/insert/delete节点,是一条SQL语句
            MappedStatement mappedStatement = (MappedStatement)invocation.getArgs()[0];
            Object parameter = null;
            // 获取参数,if语句成立,表示sql语句有参数,参数格式是map形式
            if (invocation.getArgs().length > 1)
            {
                parameter = invocation.getArgs()[1];

            }
            String sqlId = mappedStatement.getId(); // 获取到节点的id,即sql语句的id

            System.out.println("sqlId = " + sqlId);

            BoundSql boundSql = mappedStatement.getBoundSql(parameter); // BoundSql就是封装myBatis最终产生的sql类
            Configuration configuration = mappedStatement.getConfiguration(); // 获取节点的配置
            String sql = getSql(configuration, boundSql, sqlId); // 获取到最终的sql语句

            Map map= HttpAspect.requsetLogKey.get();

            String key=(String)map.get("requestKey");


            System.out.println("requestKey::"+key+"   sql = " + sql);

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        // 执行完上面的任务后,不改变原有的sql执行过程
        return invocation.proceed();
    }

    // 封装了一下sql语句,使得结果返回完整xml路径下的sql语句节点id + sql语句
    public static String getSql(Configuration configuration, BoundSql boundSql, String sqlId)
    {
        String sql = showSql(configuration, boundSql);
//        StringBuilder str = new StringBuilder(100);
//        str.append(sqlId);
//        str.append(":");
//        str.append(sql);
        return sql;
    }


    // 如果参数是String,则添加单引号, 如果是日期,则转换为时间格式器并加单引号; 对参数是null和不是null的情况作了处理
    private static String getParameterValue(Object obj)
    {
        String value = null;
        if (obj instanceof String)
        {
            value = "'" + obj.toString() + "'";
        }
        else if (obj instanceof Date)
        {
            DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT,
                    DateFormat.DEFAULT, Locale.CHINA);
            value = "'" + formatter.format(new Date()) + "'";
        }
        else
        {
            if (obj != null)
            {
                value = obj.toString();
            }
            else
            {
                value = "";
            }

        }
        return value;
    }


    // 进行?的替换
    public static String showSql(Configuration configuration, BoundSql boundSql)
    {
        // 获取参数
        Object parameterObject = boundSql.getParameterObject();
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        // sql语句中多个空格都用一个空格代替
        String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
        if (CollectionUtils.isNotEmpty(parameterMappings) && parameterObject != null)
        {
            // 获取类型处理器注册器,类型处理器的功能是进行java类型和数据库类型的转换
            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
            // 如果根据parameterObject.getClass()可以找到对应的类型,则替换
            if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass()))
            {
                sql = sql.replaceFirst("\\?",
                        Matcher.quoteReplacement(getParameterValue(parameterObject)));

            }
            else
            {
                // MetaObject主要是封装了originalObject对象,提供了get和set的方法用于获取和设置originalObject的属性值,主要支持对JavaBean、Collection、Map三种类型对象的操作
                MetaObject metaObject = configuration.newMetaObject(parameterObject);
                for (ParameterMapping parameterMapping : parameterMappings)
                {
                    String propertyName = parameterMapping.getProperty();
                    if (metaObject.hasGetter(propertyName))
                    {
                        Object obj = metaObject.getValue(propertyName);
                        sql = sql.replaceFirst("\\?",
                                Matcher.quoteReplacement(getParameterValue(obj)));
                    }
                    else if (boundSql.hasAdditionalParameter(propertyName))
                    {
                        // 该分支是动态sql
                        Object obj = boundSql.getAdditionalParameter(propertyName);
                        sql = sql.replaceFirst("\\?",
                                Matcher.quoteReplacement(getParameterValue(obj)));
                    }
                    else
                    {
                        // 打印出缺失,提醒该参数缺失并防止错位
                        sql = sql.replaceFirst("\\?", "缺失");
                    }
                }
            }
        }
        return sql;
    }

    @Override
    public Object plugin(Object o) {
        System.out.println("7777777777777777777777777777");
        return Plugin.wrap(o, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

添加文件:

spring.factories

路径:resources/META-INF

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.school.oauth.config.MyBatisConfig

启动类:

spring boot 启动类,需要注意,添加了

excludeFilters = @ComponentScan.Filter(
type = FilterType.REGEX,
pattern = "com.school.oauth.config.MyBatisConfig")
OauthApplication.java
package com.school.oauth;

import com.school.oauth.db.DynamicDataSourceRegister;
import org.apache.catalina.filters.CorsFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.*;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Import(DynamicDataSourceRegister.class)
@SpringBootApplication
@ComponentScan(basePackages = {
		"com.school.oauth.common",
		"com.school.oauth.config",
		"com.school.oauth.controller",
		"com.school.oauth.db",
		"com.school.oauth.entity.pojo",
		"com.school.oauth.mapper",
		"com.school.oauth.service",
		"com.school.oauth.util",
		"com.school.oauth.aop"},
		excludeFilters = @ComponentScan.Filter(
		type = FilterType.REGEX,
		pattern = "com.school.oauth.config.MyBatisConfig"))
public class OauthApplication  {

	public static void main(String[] args) {
		SpringApplication.run(OauthApplication.class, args);
	}

}

 

参考:https://www.jianshu.com/p/8dc9f8a4cce9

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值