1.自定义版本号注解
@Target({ElementType.METHOD, ElementType.TYPE}) // 类上和方法上都可以
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping //spring的元注释,表示 Web 映射注释
public @interface ApiVersion {
/**
* 自定义版本号
*/
int value() default 1;
}
2.自定义版本号筛选规则
实现RequestCondition(请求映射条件的合同)
public class ApiVersionCondition implements RequestCondition<ApiVersionCondition> {
/**
* 匹配v[n]
*/
private final static Pattern VERSION_PREFIX_PATTERN = Pattern.compile(".*v(\\d+).*");
private final int apiVersion;
public int getApiVersion() {
return apiVersion;
}
public ApiVersionCondition(int apiVersion) {
this.apiVersion = apiVersion;
}
/**
* 版本号合并方式,按最后定义的版本号为准
*
* @param otherVersionCondition
* @return
*/
@Override
public ApiVersionCondition combine(ApiVersionCondition otherVersionCondition) {
return new ApiVersionCondition(otherVersionCondition.getApiVersion());
}
/**
* 检查uri是否包含版本相关的字段
*
* @param httpServletRequest
* @return
*/
@Override
public ApiVersionCondition getMatchingCondition(HttpServletRequest httpServletRequest) {
Matcher m = VERSION_PREFIX_PATTERN.matcher(httpServletRequest.getRequestURI());
if (m.find()) {
int version = Integer.parseInt(m.group(1));
if (version >= this.apiVersion) {
return this;
}
}
return null;
}
@Override
public int compareTo(ApiVersionCondition otherVersionCondition, HttpServletRequest httpServletRequest) {
// 优先匹配最新的版本号
return Integer.compare(otherVersionCondition.getApiVersion(), this.apiVersion);
}
}
3.自定义版本号匹配拦截器
继承RequestMappingHandlerMapping来创建自定义的RequestCondition
public class ApiRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
/**
* 定义类级别的映射
*
* @param handlerType
* @return
*/
@Override
protected RequestCondition<ApiVersionCondition> getCustomTypeCondition(Class<?> handlerType) {
ApiVersion apiVersion = AnnotationUtils.findAnnotation(handlerType, ApiVersion.class);
return createCondition(apiVersion);
}
/**
* 定义方法级别的映射
*
* @param method
* @return
*/
@Override
protected RequestCondition<ApiVersionCondition> getCustomMethodCondition(Method method) {
ApiVersion apiVersion = AnnotationUtils.findAnnotation(method, ApiVersion.class);
return createCondition(apiVersion);
}
private RequestCondition<ApiVersionCondition> createCondition(ApiVersion apiVersion) {
return apiVersion == null ? null : new ApiVersionCondition(apiVersion.value());
}
}
4.注册版本管理器
@Configuration
public class ApiVersionMappingConfig implements WebMvcRegistrations {
@Override
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
return new ApiRequestMappingHandlerMapping();
}
}
5.使用
在方法上添加注解
或者在类上添加注解
来源于项目中他人编写的版本控制逻辑,原理还未深究…