内容
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<Method> 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时可以走到拦截器中了
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/93695.html