当前使用版本

V 3.5.3.2

需求背景

在自定义InnerInterceptor时,发现项目本身用的框架已提前加入了一些如分页、日志等InnerInterceptor。这样的话我就无法将我自定义的InnerInterceptor作为第一个执行的InnerInterceptor。 项目框架中对MybatisPlusInterceptor 的配置如下:


    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(
        ObjectProvider<QueryInterceptor[]> queryInterceptors,
        TenantLineInnerInterceptor tenantLineInnerInterceptor,
        MybatisPlusProperties mybatisPlusProperties
    ) {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

               // 项目框架直接对创建出来的interceptor加入了固定的一些InnerInterceptor
        if (mybatisPlusProperties.getTenantMode()) {
            interceptor.addInnerInterceptor(tenantLineInnerInterceptor);
        }

        BladePaginationInterceptor paginationInterceptor = new BladePaginationInterceptor();
        QueryInterceptor[] queryInterceptorArray = queryInterceptors.getIfAvailable();
        if (queryInterceptorArray != null && ObjectUtil.isNotEmpty(queryInterceptorArray)) {
            AnnotationAwareOrderComparator.sort(queryInterceptorArray);
            paginationInterceptor.setQueryInterceptors(queryInterceptorArray);
        }

        paginationInterceptor.setMaxLimit(mybatisPlusProperties.getPageLimit());
        paginationInterceptor.setOverflow(mybatisPlusProperties.getOverflow());
        paginationInterceptor.setOptimizeJoin(mybatisPlusProperties.getOptimizeJoin());
        interceptor.addInnerInterceptor(paginationInterceptor);
        return interceptor;
    }

由于这个写法创建出来的MybatisPlusInterceptor直接就预加入了一些InnerInterceptor,导致无法复用原有的配置,如果我需要将我自定义的Interceptor作为第一个被调用的interceptor就要把这个配置复制一份,类似如下代码:


    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(
        ObjectProvider<QueryInterceptor[]> queryInterceptors,
        TenantLineInnerInterceptor tenantLineInnerInterceptor,
        MybatisPlusProperties mybatisPlusProperties,
        UserGridCodeGetter userGridCodeGetter
    ) {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        if (userGridCodeGetter != null)
            interceptor.addInnerInterceptor(new UserGridLimitInterceptor(userGridCodeGetter));

        // 下面这一段是从项目框架中复制过来的,不必关心在干什么
        if (mybatisPlusProperties.getTenantMode()) {
            interceptor.addInnerInterceptor(tenantLineInnerInterceptor);
        }

        BladePaginationInterceptor paginationInterceptor = new BladePaginationInterceptor();
        QueryInterceptor[] queryInterceptorArray = queryInterceptors.getIfAvailable();
        if (queryInterceptorArray != null && ObjectUtil.isNotEmpty(queryInterceptorArray)) {
            AnnotationAwareOrderComparator.sort(queryInterceptorArray);
            paginationInterceptor.setQueryInterceptors(queryInterceptorArray);
        }

        paginationInterceptor.setMaxLimit(mybatisPlusProperties.getPageLimit());
        paginationInterceptor.setOverflow(mybatisPlusProperties.getOverflow());
        paginationInterceptor.setOptimizeJoin(mybatisPlusProperties.getOptimizeJoin());
        interceptor.addInnerInterceptor(paginationInterceptor);
        return interceptor;
    }


针对以上需求,不知道在不改动MP本身API的情况下🫢,还有什么比较好的做法

对这种需求,建议MP可以有以下两种优化方式

1、优先级模式

支持设置InnerInterceptor的优先级,在MybatisPlusInterceptor中按照优先级有序的方式存储InnerInterceptor列表

public void injectCustomInterceptor(@Autowired MybatisPlusInterceptor interceptor) {
        interceptor.addInnerInterceptor(interceptor = new MyCustomInterceptor(), priority = 1);
}

当然了,除了在addInnerInterceptor方法中允许设置优先级,也可以在InnerInterceptor接口中增加一个方法返回自己的优先级,并且作为接口的default方法,提供默认的优先级参数,这样可以兼容之前的代码

2、可指定InnerInterceptor的插入位置

支持指定插入位置,直接调用List.add(position, element)的方式:

public void injectCustomInterceptor(@Autowired MybatisPlusInterceptor interceptor) {
        interceptor.addInnerInterceptor(position = 0,interceptor = new MyCustomInterceptor());
}

非常乐意提供PR😊😊😊

Comment From: nieqiurong

用spring的@order控制. 3.5.4开始已经支持默认缺省注入了, MyBatis-Plus MybatisPlusInterceptor 能否支持自定义 InnerInterceptor 的调用顺序 MyBatis-Plus MybatisPlusInterceptor 能否支持自定义 InnerInterceptor 的调用顺序

Comment From: kiiiooo

赞同这种做法,这个ISSUE关了,感谢回复