源代码版本 : spring-webmvc-5.1.4.RELEASE
概述
接口RequestCondition
是Spring MVC
对一个请求匹配条件的概念建模。最终的实现类可能是针对以下情况之一:路径匹配,头部匹配,请求参数匹配,可产生MIME
匹配,可消费MIME
匹配,请求方法匹配,或者是以上各种情况的匹配条件的一个组合。
源代码分析
RequestCondition
接口定义
package org.springframework.web.servlet.mvc.condition;
import javax.servlet.http.HttpServletRequest;
import org.springframework.lang.Nullable;
public interface RequestCondition<T> {
// 和另外一个请求匹配条件合并,具体合并逻辑由实现类提供
T combine(T other);
// 检查当前请求匹配条件和指定请求request是否匹配,如果不匹配返回null,
// 如果匹配,生成一个新的请求匹配条件,该新的请求匹配条件是当前请求匹配条件
// 针对指定请求request的剪裁。
// 举个例子来讲,如果当前请求匹配条件是一个路径匹配条件,包含多个路径匹配模板,
// 并且其中有些模板和指定请求request匹配,那么返回的新建的请求匹配条件将仅仅
// 包含和指定请求request匹配的那些路径模板。
@Nullable
T getMatchingCondition(HttpServletRequest request);
// 针对指定的请求对象request比较两个请求匹配条件。
// 该方法假定被比较的两个请求匹配条件都是针对该请求对象request调用了
// #getMatchingCondition方法得到的,这样才能确保对它们的比较
// 是针对同一个请求对象request,这样的比较才有意义(最终用来确定谁是
// 更匹配的条件)。
int compareTo(T other, HttpServletRequest request);
}
由接口源代码可以看出,接口RequestCondition
是一个泛型接口。事实上,它的泛型参数T
通常也会是一个RequestCondition
对象。
抽象基类实现AbstractRequestCondition
框架对接口RequestCondition
有一组具体实现类。对这些具体实现类的一些通用逻辑,比如equals
,hashCode
和toString
,是被放到抽象基类AbstractRequestCondition
来实现的。同时AbstractRequestCondition
还通过protected
抽象方法约定了实现类其他的一些内部通用逻辑,具体如下所示:
package org.springframework.web.servlet.mvc.condition;
import java.util.Collection;
import java.util.Iterator;
import org.springframework.lang.Nullable;
/**
* @param <T> the type of objects that this RequestCondition can be combined
* with and compared to
*/
public abstract class AbstractRequestCondition<T extends AbstractRequestCondition<T>> implements RequestCondition<T> {
/**
* 当前请求匹配条件对象是否内容为空
* @return true if empty; false otherwise
*/
public boolean isEmpty() {
return getContent().isEmpty();
}
/**
* 一个请求匹配条件可能由多个部分组成,这些组成部分被包装成一个名为 content 的集合
* 比如 :
* 对于请求路径匹配条件,可能有多个 URL pattern,
* 对于请求方法匹配条件,可能有多个 HTTP request method,
* 对于请求参数匹配条件,可能有多个 param 表达式 .
* @return a collection of objects, never null , 可能为空集合
*/
protected abstract Collection<?> getContent();
/**
* The notation to use when printing discrete items of content.
* 将该条件作为字符串展示时,各个组成部分之间的中缀标识符。比如 "||" 或者 "&&" 等。
* For example {@code " || " for URL patterns or {@code " && "} for param expressions.
*/
protected abstract String getToStringInfix();
// equlas 实现
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (other == null || getClass() != other.getClass()) {
return false;
}
return getContent().equals(((AbstractRequestCondition<?>) other).getContent());
}
// hashCode 实现
@Override
public int hashCode() {
return getContent().hashCode();
}
// toString 实现
@Override
public String toString() {
StringBuilder builder = new StringBuilder("[");
for (Iterator<?> iterator = getContent().iterator(); iterator.hasNext();) {
Object expression = iterator.next();
builder.append(expression.toString());
if (iterator.hasNext()) {
builder.append(getToStringInfix());
}
}
builder.append("]");
return builder.toString();
}
}
针对某种请求匹配条件具体实现类
实现类 | 简介 |
---|---|
PatternsRequestCondition | 路径匹配条件 |
RequestMethodsRequestCondition | 请求方法匹配条件 |
ParamsRequestCondition | 请求参数匹配条件 |
HeadersRequestCondition | 头部信息匹配条件 |
ConsumesRequestCondition | 可消费MIME 匹配条件 |
ProducesRequestCondition | 可生成MIME 匹配条件 |
该表格提到的RequestCondition
具体实现类都继承自AbstractRequestCondition
抽象基类,都是针对请求匹配的某一个方面:请求路径,请求头部,请求方法,请求参数,可消费MIME
,可生成MIME
等等。
另外框架还提供了一个实现类RequestConditionHolder
,这是一个匹配条件持有器,用于持有某个RequestCondition
对象。如果你想持有一个RequestCondition
对象,但其类型事先不可知,那么这种情况下该工具很有用。但要注意的是如果要合并或者比较两个RequestConditionHolder
对象,也就是二者所持有的RequestCondition
对象,那么二者所持有的RequestCondition
对象必须是类型相同的,否则会抛出异常ClassCastException
。
实际上,以上面的这些实现类为基础, Spring MVC
有另外一个RequestCondition
实现类RequestMappingInfo
,该实现类不是针对请求匹配某个一方面的实现类,而是包含了一个请求匹配的所有方面。我们会在另外一篇文章中作介绍。
参考文章
Spring MVC 概念模型 : 注解 @RequestMapping 信息载体 RequestMappingInfo
Spring MVC HandlerMapping : RequestMappingHandlerMapping 源代码解析
————————————————
版权声明:本文为CSDN博主「安迪源文」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/andy_zhang2007/article/details/88913776