网站首页 > 教程文章 正文
一、Servlet 容器与 DispatcherServlet 的启动博弈
1. Tomcat 初始化阶段
java
// Tomcat 初始化流程
StandardContext#startInternal()
→ LifecycleBase#start()
→ ContextConfig#configureStart()
→ SpringServletContainerInitializer.onStartup()
关键步骤:
- 通过 SPI 机制加载SpringServletContainerInitializer
- 扫描WebApplicationInitializer实现类(Spring Boot 通过SpringBootServletInitializer实现)
- 创建AnnotationConfigWebApplicationContext上下文
2. DispatcherServlet 的九层继承体系
HttpServletBean → FrameworkServlet → DispatcherServlet
↑ ↑ ↑
配置参数绑定 上下文初始化 请求分发中枢
核心初始化方法:
java
// FrameworkServlet#initWebApplicationContext()
protected WebApplicationContext initWebApplicationContext() {
// 父子容器关联(Root WebApplicationContext 与 Servlet WebApplicationContext)
if (this.webApplicationContext == null) {
this.webApplicationContext = createWebApplicationContext(rootContext);
}
// 初始化策略组件
initStrategies(this.webApplicationContext);
}
二、请求处理七步解剖模型
1. doDispatch() 方法全流程
java
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
try {
// Step1: 获取HandlerExecutionChain
mappedHandler = getHandler(processedRequest);
// Step2: 获取HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Step3: 执行拦截器preHandle()
if (!mappedHandler.applyPreHandle(processedRequest, response)) return;
// Step4: 实际调用Controller方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// Step5: 处理视图名称(ViewName)
applyDefaultViewName(processedRequest, mv);
// Step6: 执行拦截器postHandle()
mappedHandler.applyPostHandle(processedRequest, response, mv);
// Step7: 渲染视图并触发afterCompletion()
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
} catch (Exception ex) {
// 异常处理流程
}
}
2. HandlerMapping 的三种实现对比
类型 | 实现类 | 匹配策略 | 适用场景 |
注解控制器映射 | RequestMappingHandler | Ant路径+HTTP方法+headers | RESTful API |
简单URL映射 | SimpleUrlHandlerMapping | 精确路径匹配 | 静态资源映射 |
Bean名称映射 | BeanNameUrlHandlerMapping | Bean名称与URL前缀匹配 | 传统XML配置方式 |
三、参数绑定的八层包装机制
1.
HandlerMethodArgumentResolver 解析链
java
// 参数解析器执行顺序(部分关键解析器)
1. RequestParamMethodArgumentResolver // @RequestParam
2. RequestPartMethodArgumentResolver // @RequestPart
3. RequestResponseBodyMethodProcessor // @RequestBody
4. ServletRequestMethodArgumentResolver // HttpServletRequest
5. ModelMethodProcessor // Model/Map参数
6. PathVariableMethodArgumentResolver // @PathVariable
2. 数据绑定核心类
java
public class DataBinder extends WebDataBinder {
// 绑定流程
public void bind(PropertyValues pvs) {
MutablePropertyValues mpvs = (pvs instanceof MutablePropertyValues) ?
(MutablePropertyValues) pvs : new MutablePropertyValues(pvs);
doBind(mpvs);
}
// 类型转换入口
protected void convertIfNecessary(Object value, Class<?> targetType,
MethodParameter methodParam) throws TypeMismatchException {
// 使用ConversionService进行转换
}
}
3. 自定义参数解析器示例
java
public class JwtTokenArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(JwtToken.class);
}
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
return JwtUtils.parse(request.getHeader("Authorization"));
}
}
四、视图解析的六阶渲染流程
1. ViewResolver 链式解析
java
// 视图解析器优先级
1. ContentNegotiatingViewResolver // 内容协商
2. BeanNameViewResolver // Bean名称匹配
3. InternalResourceViewResolver // JSP/HTML模板
4. ThymeleafViewResolver // Thymeleaf模板
5. FreeMarkerViewResolver // FreeMarker模板
6. MappingJackson2JsonView // JSON输出
2. 视图渲染关键步骤
java
// AbstractView#render()
public void render(@Nullable Map<String, ?> model,
HttpServletRequest request, HttpServletResponse response) throws Exception {
// 合并静态属性与动态模型
Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
// 准备响应头
prepareResponse(request, response);
// 实际渲染逻辑
renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
}
3. 内容协商策略矩阵
策略类型 | 实现类 | 支持格式 |
后缀匹配 | SuffixContentNegotiationStrategy | .json/.xml |
请求参数 | ParameterContentNegotiationStrategy | format=json |
Accept头匹配 | HeaderContentNegotiationStrategy | Accept: application/json |
固定内容类型 | FixedContentNegotiationStrategy | 强制指定类型 |
五、异常处理的五层防御体系
1. HandlerExceptionResolver 处理链
java
// 异常处理器优先级
1. ExceptionHandlerExceptionResolver // @ExceptionHandler
2. ResponseStatusExceptionResolver // @ResponseStatus
3. DefaultHandlerExceptionResolver // Spring默认异常转换
4. SimpleMappingExceptionResolver | XML配置的异常映射
2. @ControllerAdvice 的生效机制
java
复制
// ExceptionHandlerMethodResolver 源码片段
private Map<Class<? extends Throwable>, Method> detectExceptionMappings(Class<?> handlerType) {
Map<Class<? extends Throwable>, Method> result = new HashMap<>();
for (Method method : HandlerMethodSelector.selectMethods(handlerType, EXCEPTION_HANDLER_METHOD_FILTER)) {
for (Class<? extends Throwable> exceptionType : detectExceptionMappings(method)) {
result.put(exceptionType, method);
}
}
return result;
}
3. 全局异常处理示例
java
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
@ResponseBody
public ResponseEntity<ErrorResult> handleBusinessException(BusinessException ex) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new ErrorResult(ex.getCode(), ex.getMessage()));
}
}
六、性能优化三大核心策略
1. HandlerMapping 缓存优化
java
// AbstractHandlerMethodMapping 的匹配缓存
private final Map<T, HandlerMethod> handlerMethods = new LinkedHashMap<>();
private final MultiValueMap<String, T> urlMap = new LinkedMultiValueMap<>();
// 使用ConcurrentHashMap提升并发性能
private final Map<HandlerMethod, CorsConfiguration> corsLookup =
new ConcurrentHashMap<>();
2. 视图渲染加速方案
- 开启模板引擎缓存(Thymeleaf的spring.thymeleaf.cache=true)
- 使用静态资源版本号(ResourceUrlProvider)
- 启用Gzip压缩(server.compression.enabled=true)
3. 异步处理模式
java
复制
@GetMapping("/async")
public Callable<String> asyncProcessing() {
return () -> {
// 长时间处理逻辑
TimeUnit.SECONDS.sleep(5);
return "result";
};
}
// 配置异步线程池
@Bean
public AsyncTaskExecutor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
return executor;
}
总结:Spring MVC 架构设计的六大精妙之处
- 分层架构:清晰划分HandlerMapping、HandlerAdapter等职责边界
- 策略模式:通过可插拔组件实现高度扩展性
- 模板方法:在DispatcherServlet中定义处理骨架
- 适配器模式:统一不同处理器类型的调用方式
- 责任链模式:拦截器链、参数解析器链的协同工作
- 观察者模式:通过事件机制实现生命周期管理
通过mvn dependency:tree -Dincludes=
org.springframework:spring-webmvc可查看完整依赖结构,结合Arthas的watch
org.springframework.web.servlet.DispatcherServlet doDispatch命令进行实时方法观测,能够更直观理解处理流程。深入掌握这些原理,开发者可精准定位性能瓶颈,实现框架深度定制。
- 上一篇: 揭秘HTTP:从诞生到现代的演进之旅
- 下一篇: Python中的HTTP访问利器
猜你喜欢
- 2025-05-22 Spring Boot跨域问题终极解决方案:3种方法根治CORS报错
- 2025-05-22 详细介绍一下Spring Cloud GateWay中Router的使用?
- 2025-05-22 SpringBoot应用中使用拦截器实现路由转发
- 2025-05-22 谷歌浏览器HTTP不跳转HTTPS设置方法
- 2025-05-22 Java对接DeepSeek API:从零开始打造智能应用
- 2025-05-22 Python小案例70- URL和HTTP协议介绍及语法
- 2025-05-22 HTTPS通信原理及与HTTP的区别
- 2025-05-22 Python中的HTTP访问利器
- 2025-05-22 揭秘HTTP:从诞生到现代的演进之旅
- 2025-05-22 Wuzz - Web 开发与安全测试利器,交互式 HTTP 工具
- 05-25干货 | 一步步部署 Flask 应用
- 05-25别再去找Docker命令了,你要的常用的全都在这
- 05-25如果您删除Windows11上的“Program Files”文件夹会发生什么?
- 05-25家用nas最常用的docker容器及部署方法
- 05-25你好 dotnet run file, 再见 csproj
- 05-25China committed to continuing contributions to global health: delegation
- 05-25Chinese, German experts urge cooperation during Eurasia relations seminar
- 05-25Peace of paramount importance for region
- 最近发表
-
- 干货 | 一步步部署 Flask 应用
- 别再去找Docker命令了,你要的常用的全都在这
- 如果您删除Windows11上的“Program Files”文件夹会发生什么?
- 家用nas最常用的docker容器及部署方法
- 你好 dotnet run file, 再见 csproj
- China committed to continuing contributions to global health: delegation
- Chinese, German experts urge cooperation during Eurasia relations seminar
- Peace of paramount importance for region
- after和in用法解析
- China's top diplomat to chair third China-Pacific Island countries foreign ministers' meeting
- 标签列表
-
- location.href (44)
- document.ready (36)
- git checkout -b (34)
- 跃点数 (35)
- 阿里云镜像地址 (33)
- qt qmessagebox (36)
- mybatis plus page (35)
- vue @scroll (38)
- 堆栈区别 (33)
- 什么是容器 (33)
- sha1 md5 (33)
- navicat导出数据 (34)
- 阿里云acp考试 (33)
- 阿里云 nacos (34)
- redhat官网下载镜像 (36)
- srs服务器 (33)
- pico开发者 (33)
- https的端口号 (34)
- vscode更改主题 (35)
- 阿里云资源池 (34)
- os.path.join (33)
- redis aof rdb 区别 (33)
- 302跳转 (33)
- http method (35)
- js array splice (33)