Mybatis Plus 插件失效问题记录
- 1. 问题发生场景
- 2.问题发生原理与解决方法
1. 问题发生场景
在配置了Mybatis Plus
分页查询后,自定义拦截器(插件)失效。
@SpringBootApplication
public class MybatisPlusDemoApplication {public static void main(String[] args) {SpringApplication.run(MybatisPlusDemoApplication.class, args);}// Mybatis Plus 分页插件@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());return mybatisPlusInterceptor;}
}
自定义拦截器
@Component
@Intercepts({@Signature(type = Executor.class,method = "query",args = {MappedStatement.class, Object.class, org.apache.ibatis.session.RowBounds.class, org.apache.ibatis.session.ResultHandler.class})
})
public class MyInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {// 在方法执行前的逻辑System.out.println("Before executing the method...");// 执行原方法Object result = invocation.proceed();// 在方法执行后的逻辑System.out.println("After executing the method...");return result;}@Overridepublic Object plugin(Object target) {return Interceptor.super.plugin(target);}@Overridepublic void setProperties(Properties properties) {Interceptor.super.setProperties(properties);}
}
测试:
在Mybatis Plus
的自动配置类中打上断点,可以看到自定义拦截器成功加载到了Spring容器
中但还是失效了。
注释掉Mybatis Plus
的分页查询后再测试:自定义拦截器生效
2.问题发生原理与解决方法
由上面的测试可以看出问题和Mybatis Plus
分页插件有关,具体原因就是Mybatis Plus
的分页插件先执行,在MybatisPlusInterceptor
的intercept
方法中并不会执行原始方法(invocation.proceed()
)
解决方法就是改变拦截器的加载顺序,让自定义拦截器先执行:
Spring 提供了一个接口 BeanDefinitionRegistryPostProcessor
:用于在 Spring 容器加载 Bean 定义之后、实例化 Bean 之前对 Bean 定义进行进一步的修改或者添加。
关键的方法是 postProcessBeanDefinitionRegistry
,它接收一个 BeanDefinitionRegistry 参数,允许向注册表中动态添加或修改 Bean 定义。另一个方法是 postProcessBeanFactory
,它通常用于在实例化 Bean 之前进行一些操作。
这里我们使用postProcessBeanDefinitionRegistry
方法改变拦截器的注册顺序。
@Configuration
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {RootBeanDefinition bd = new RootBeanDefinition(MyInterceptor.class);beanDefinitionRegistry.registerBeanDefinition("MyInterceptor", bd);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {}
}
配置成功后,拦截器的注解顺序改变,自定义拦截器生效。