HandlerMapping机制
HandlerMapping是SpringMVC请求分发的核心组件,负责建立请求与处理器之间的映射关系。
核心接口定义
Java
public interface HandlerMapping {
@Nullable
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
主要实现类
| 实现类 | 作用 | 优先级 |
|---|---|---|
| RequestMappingHandlerMapping | 处理@RequestMapping注解 | 最高 |
| BeanNameUrlHandlerMapping | 处理以/开头的Bean名称 | 中 |
| SimpleUrlHandlerMapping | 处理显式配置的URL映射 | 低 |
工作流程
1. 初始化阶段
Java
// RequestMappingHandlerMapping 初始化
public void afterPropertiesSet() {
// 扫描所有带@Controller和@RequestMapping注解的Bean
initHandlerMethods();
}
protected void initHandlerMethods() {
// 获取所有候选Bean
String[] beanNames = obtainApplicationContext()
.getBeanNamesForType(Object.class);
for (String beanName : beanNames) {
// 检测并注册HandlerMethod
detectHandlerMethods(beanName);
}
}
2. 请求映射注册
Java
protected void registerHandlerMethod(Object handler, Method method,
RequestMappingInfo mapping) {
// 创建HandlerMethod并注册到MappingRegistry
HandlerMethod handlerMethod = createHandlerMethod(handler, method);
mappingRegistry.register(mapping, handlerMethod, method);
}
3. 请求处理阶段
Java
public HandlerExecutionChain getHandler(HttpServletRequest request) {
// 遍历所有HandlerMapping
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
MappingRegistry核心结构
Java
class MappingRegistry {
// URL路径 -> MappingRegistration
private final MultiValueMap<String, RequestMappingInfo> urlLookup =
new LinkedMultiValueMap<>();
// RequestMappingInfo -> HandlerMethod
private final Map<RequestMappingInfo, HandlerMethod> mappingLookup =
new LinkedHashMap<>();
// 方法名 -> RequestMappingInfo
private final Map<String, List<RequestMappingInfo>> nameLookup =
new ConcurrentHashMap<>();
}
RequestMappingInfo构建
Java
// 从@RequestMapping注解构建映射信息
private RequestMappingInfo createRequestMappingInfo(
RequestMapping requestMapping) {
return RequestMappingInfo
.paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
.methods(requestMapping.method())
.params(requestMapping.params())
.headers(requestMapping.headers())
.consumes(requestMapping.consumes())
.produces(requestMapping.produces())
.build();
}
拦截器集成
Java
public HandlerExecutionChain getHandler(HttpServletRequest request) {
// 获取HandlerMethod
HandlerMethod handler = getHandlerInternal(request);
if (handler == null) {
return null;
}
// 创建执行链,添加拦截器
HandlerExecutionChain chain = new HandlerExecutionChain(handler);
chain.addInterceptors(getAdaptedInterceptors());
return chain;
}
HandlerMapping通过MappingRegistry维护URL到Handler的映射关系,支持ant风格路径匹配和精确匹配。
要点总结
- HandlerMapping负责URL到Handler的映射解析
- RequestMappingHandlerMapping是主要实现,处理@RequestMapping注解
- MappingRegistry是核心数据结构,存储映射关系
- 支持多条件匹配:路径、方法、参数、请求头等
- 返回HandlerExecutionChain包含Handler和拦截器链
jwdev/articles/SPRINGMVC/专家/MVC核心源码执行流程/MVC核心源码执行流程/HandlerMapping机制.md
📝 发现内容有误?点击此处直接编辑