1 问题描述
利用 MyBatis 的 @Intercepts 注解自定义了一个拦截器,在纯净环境中运行正常。放入一套Spring框架中不生效。
2 原因分析
利用 IDEA 的 Jar 包图谱分析器发现存在2个不同版本的 mybatis-spring-boot-starter:
怀疑是与 com.github.pagehelper组件不兼容,因为它内部也是利用 MyBatis 的拦截器实现语句自动分页功能的。
利用Maven 的exclusions 标签进行冲突检验:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.13</version>
<exclusions>
<exclusion>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
</exclusion>
</exclusions>
</dependency>
排除掉pagehelper组件之后,我们的 MyBatis 自定义组件就运行正常了。
3 问题解决
实现 Spring 框架的 ApplicationListener,监听 ContextRefreshedEvent 事件,当所有的bean都初始化完成后1,把我们的自定义 MyBatis 拦截器注册到 SqlSessionFactory 中2。
/**
* 注册 MyBatis 自定义拦截器
*
* @author Deniro Lee
*/
@Component
public class EnrollSwitchDataSourceInterceptor implements ApplicationListener<ContextRefreshedEvent> {
private static final Logger log = LoggerFactory.getLogger(EnrollSwitchDataSourceInterceptor.class);
@Autowired
private SwitchDataSourceInterceptor switchDataSourceInterceptor;
@Autowired
private List<SqlSessionFactory> sqlSessionFactories;
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
log.info("begin enroll 'switchDataSourceInterceptor' ……");
for (SqlSessionFactory factory : sqlSessionFactories) {
factory.getConfiguration().addInterceptor(switchDataSourceInterceptor);
}
log.info("'switchDataSourceInterceptor' enrolled.");
}
}
翻看 PageHelper组件的PageHelperAutoConfiguration源代码,也是类似的实现: