SpringBoot的项目API版本控制方式

 更新时间:2026年05月14日 16:24:27   作者:梁云亮  
本文主要讲述了如何通过自定义版本控制来实现接口版本的管理,主要包括自定义版本号标记注解,重写RequestCondition和RequestMappingHandlerMapping以实现自定义的URL匹配逻辑,以及配置注册自定义的WebMvcRegistrations,最后通过测试接口页面验证了效果

第一步:自定义版本号标记注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiVersion {
    /**
     * 标识版本号,从1开始
     */
    int value() default 1;
}

第二步:重写RequestCondition,自定义url匹配逻辑

@Data
@Slf4j
public class ApiVersionCondition implements RequestCondition<ApiVersionCondition> {
    /**
     * 接口路径中的版本号前缀,如: api/v[1-n]/fun
     */
    private final static Pattern VERSION_PREFIX = Pattern.compile("/v(\\d+)/");
    private int apiVersion;

    ApiVersionCondition(int apiVersion) {
        this.apiVersion = apiVersion;
    }
    /**
     * 最近优先原则,方法定义的 @ApiVersion > 类定义的 @ApiVersion
     */
    @Override
    public ApiVersionCondition combine(ApiVersionCondition other) {
        return new ApiVersionCondition(other.getApiVersion());
    }
    /**
     * 获得符合匹配条件的ApiVersionCondition
     */
    @Override
    public ApiVersionCondition getMatchingCondition(HttpServletRequest request) {
        Matcher m = VERSION_PREFIX.matcher(request.getRequestURI());
        if (m.find()) {
            int version = Integer.valueOf(m.group(1));
            if (version >= getApiVersion()) {
                return this;
            }
        }
        return null;
    }
    /**
     * 当出现多个符合匹配条件的ApiVersionCondition,优先匹配版本号较大的
     */
    @Override
    public int compareTo(ApiVersionCondition other, HttpServletRequest request) {
        return other.getApiVersion() - getApiVersion();
    }
}

说明:

  • getMatchingCondition方法中,控制了只有版本小于等于请求参数中的版本的 ApiCondition 才满足规则
  • compareTo 指定了当有多个ApiCoondition满足这个请求时,选择最大的版本

第三步:重写RequestMappingHandlerMapping,自定义匹配的处理器

public class ApiRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
    @Override
    protected RequestCondition<?> getCustomTypeCondition(Class<?> handlerType) {
        // 扫描类上的 @ApiVersion
        ApiVersion apiVersion = AnnotationUtils.findAnnotation(handlerType, ApiVersion.class);
        return createRequestCondition(apiVersion);
    }
    @Override
    protected RequestCondition<?> getCustomMethodCondition(Method method) {
        // 扫描方法上的 @ApiVersion
        ApiVersion apiVersion = AnnotationUtils.findAnnotation(method, ApiVersion.class);
        return createRequestCondition(apiVersion);
    }
    private RequestCondition<ApiVersionCondition> createRequestCondition(ApiVersion apiVersion) {
        if (Objects.isNull(apiVersion)) {
            return null;
        }
        int value = apiVersion.value();
        Assert.isTrue(value >= 1, "Api Version Must be greater than or equal to 1");
        return new ApiVersionCondition(value);
    }
}

第四步:配置注册自定义WebMvcRegistrations

@Configuration
public class WebMvcRegistrationsConfig implements WebMvcRegistrations {
    @Override
    public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
        return new ApiRequestMappingHandlerMapping();
    }
}

第五步:编写测试接口

@RestController
@RequestMapping("/api/{version}")
public class ApiControler {
    @GetMapping("/fun")
    public String fun1() {
        return "fun 1";
    }
    @ApiVersion(5)
    @GetMapping("/fun")
    public String fun2() {
        return "fun 2";
    }
    @ApiVersion(9)
    @GetMapping("/fun")
    public String fun3() {
        return "fun 5";
    }
}

页面测试效果:

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。 

相关文章

  • javax NotBlank和Email注解失效的解决

    javax NotBlank和Email注解失效的解决

    这篇文章主要介绍了javax NotBlank和Email注解失效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • SpringBoot深入分析讲解监听器模式上

    SpringBoot深入分析讲解监听器模式上

    监听器模式,大家应该并不陌生,主要的组成要素包括了事件、监听器以及广播器;当事件发生时,广播器负责将事件传递给所有已知的监听器,而监听器会对自己感兴趣的事件进行处理
    2022-07-07
  • Java中List.sort()自定义排序规则几种方式

    Java中List.sort()自定义排序规则几种方式

    Java中可通过Comparator匿名类、Lambda表达式、静态方法、自定义对象及实现Comparable接口实现List排序,这篇文章主要介绍了Java中List.sort()自定义排序规则几种方式,需要的朋友可以参考下
    2025-06-06
  • 几个好用Maven镜像仓库地址(小结)

    几个好用Maven镜像仓库地址(小结)

    这篇文章主要介绍了几个好用Maven镜像仓库地址(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Java使用国密算法实现数据加密传输的完整示例

    Java使用国密算法实现数据加密传输的完整示例

    文章主要介绍了使用SM2和SM4算法进行混合加密的完整方案,包括前后端协议、SpringBoot后端代码实现、前端代码实现以及注意事项,并提供了生产环境的建议和最小可验证步骤,需要的朋友可以参考下
    2026-03-03
  • Java 详细讲解线程的状态及部分常用方法

    Java 详细讲解线程的状态及部分常用方法

    在Java程序中,一个线程对象只能调用一次start()方法启动新线程,并在新线程中执行run()方法。一旦run()方法执行完毕,线程就结束了,本篇来讲解Java线程的状态以及部分常用方法
    2022-04-04
  • Java中的访问修饰符详细解析

    Java中的访问修饰符详细解析

    以下是对Java中的访问修饰符进行了详细的分析介绍,需要的朋友可以过来参考下
    2013-09-09
  • Java数组拷贝的四种常用方式总结

    Java数组拷贝的四种常用方式总结

    数组是 Java 最基础的数据结构之一,而 数组的拷贝(复制) 是开发中经常遇到的需求,Java 提供了多种数组复制方式,每种方式都有自己的特点和适用场景,本篇文章将系统总结 Java 中 数组拷贝的 4 种常用方式,需要的朋友可以参考下
    2025-12-12
  • MySQL MAX(IF())中table.column有值但显示default的解决方案

    MySQL MAX(IF())中table.column有值但显示default的解决方案

    这篇文章主要介绍了MySQL MAX(IF())中table.column有值但显示default的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-11-11
  • Java开发中读取XML与properties配置文件的方法

    Java开发中读取XML与properties配置文件的方法

    这篇文章主要介绍了Java开发中读取XML与properties配置文件的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-01-01

最新评论