在配置了Mybatis Plus
分页查询后,自定义拦截器(插件)失效。
@SpringBootApplication
public class MybatisPlusDemoApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusDemoApplication.class, args);
}
// Mybatis Plus 分页插件
@Bean
public 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 {
@Override
public 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;
}
@Override
public Object plugin(Object target) {
return Interceptor.super.plugin(target);
}
@Override
public void setProperties(Properties properties) {
Interceptor.super.setProperties(properties);
}
}
在Mybatis Plus
的自动配置类中打上断点,可以看到自定义拦截器成功加载到了Spring容器
中但还是失效了。
注释掉Mybatis Plus
的分页查询后再测试:自定义拦截器生效
由上面的测试可以看出问题和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 {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
RootBeanDefinition bd = new RootBeanDefinition(MyInterceptor.class);
beanDefinitionRegistry.registerBeanDefinition("MyInterceptor", bd);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
配置成功后,拦截器的注解顺序改变,自定义拦截器生效。