栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring自定义数据源配置不当引起的Mybatis拦截器Interceptors 失效/不生效

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring自定义数据源配置不当引起的Mybatis拦截器Interceptors 失效/不生效

目录
  • 内容
    • Interceptor接口与@Intercepts注解
    • PageHelper实现拦截器
    • 默认数据源与拦截器
    • 自定义数据源与拦截器的问题
    • 自定义数据源注入拦截器

内容 Interceptor接口与@Intercepts注解

org.apache.ibatis.plugin.Interceptor 是ibatis包的接口,

org.apache.ibatis.plugin.Intercepts 是ibatis包的注解

我们可以实现Interceptor 接口,并标注@Intercepts注解,

做一个mybatis执行SQL时的拦截器。

PageHelper实现拦截器

著名Mybatis插件Pagehelper就是这样实现了它的拦截器:

com.github.pagehelper.PageInterceptor

com.github.pagehelper.QueryInterceptor

@Intercepts(
    {
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
    }
)
public class QueryInterceptor implements Interceptor {
	...
}
默认数据源与拦截器


默认配置下,sqlSessionFactory自己添加了拦截器

自定义数据源与拦截器的问题

不过最近同事那出了一个问题,系统之前使用这个拦截器没问题,突然就不能用了。

通过排查Mybatis源码,调用到拦截器的栈如下:

可以看到,在org.apache.ibatis.plugin.Plugin的方法中,会调用拦截器实现类的的intercept方法

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  try {
    Set methods = signatureMap.get(method.getDeclaringClass());
    if (methods != null && methods.contains(method)) {
      return interceptor.intercept(new Invocation(target, method, args));
    }
    return method.invoke(target, args);
  } catch (Exception e) {
    throw ExceptionUtil.unwrapThrowable(e);
  }
}

那么走不到拦截器,说明没注入,

我们查看对应mapper对象,看sqlSessionFactory中有没有拦截器,路径如下:

((InterceptorChain)((Configuration)((DefaultSqlSessionFactory)((SqlSessionTemplate)((MapperProxy)this.h).sqlSession).sqlSessionFactory).configuration).interceptorChain).interceptors

发现自定义的数据源时没有的,如果是Spring默认数据源配置,会帮我们注入好,如下

自定义数据源注入拦截器
//1.在自定义配置类上@import对应拦截器,供SpringBoot对其装配,其实不写这一步也能让拦截器生效,写了可以让下面注入的属性不报红,还没细看如何自动注入的拦截器,不过大概就是该注解所标注的类、该接口的实现类都进行了BeanDefinition的注册之类的
@import({***Interceptor.class, ***Interceptor.class})

//注入拦截器
	@Autowired
    private ***Interceptor ***Interceptor;
    @Autowired
    private ***Interceptor ***Interceptor;


//3.在生成SqlSessionFactory的方法中,通过setPlugins设置拦截器
	@Bean
    @Primary
    public SqlSessionFactory sqlSessionFactoryFfhj() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(ffhjds);
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*.xml")
        );
        //重点
        factoryBean.setPlugins(new Interceptor[]{***Interceptor, ***Interceptor});
        return factoryBean.getObject();
    }

测试一遍,使用mapper时可以走到拦截器中了

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/322193.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号