众所周知在Java
企业级应用开发的大环境中,Spring Framework
的地位举足轻重,之所以会是这样就是因为Spring Framework
具备以下几点属性:
1. 基于POJO的轻量级和最小侵入性编程
2. 通过依赖注入和面向接口的松耦合
3. 基于切面和惯性进行声明式编程
4. 通过切面和模板减少样板式编码
Spring Framework
具备了以上属性,开发跟后期维护会更加便利,依赖关系的明确使得开发效率有了极大的提高,同时也增强了代码的可读性和健壮性,这也就是Spring Framework
深受企业级应用青睐的原因。
本文主要讨论基于Spring Framework
的web
项目开发神器Spring Web Mvc
,在mvc
构建思想的加持下,web
项目的开发及使用变得更加便利,对于Spring Framework
的功能只是一带而过,后续会有更多更深入的分析。
以下是从百科翻译的Mvc
思想内容
Model(模型)是应用程序中用于处理应用程序数据逻辑的部分。 通常模型对象负责在数据库中存取数据。
View(视图)是应用程序中处理数据显示的部分。 通常视图是依据模型数据创建的。
Controller(控制器)是应用程序中处理用户交互的部分。 通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
Spring Web Mvc
其一:Spring
面向Bean
的开发为对象管理提供便利。
其二:Mvc
思想在Spring Web Mvc
中的体现,model
的体现主要是数据模型,比如说是Pojo
对象数据的模型,View
的体现主要是视图模板的渲染,Controller
的体现主要是业务逻辑的处理。
View
和Model
的组合是观察者模式体现,前者随后者的变化而改变;View
自身可能会存在多个视图的组合,即组合模式的体现;对于不同的handler
处理的流程是一样的,这也是策略模式的体现。
Spring Web Mvc
工作流程图本次不做过多的陈述,详情可以参照之前的一篇文章:Spring Mvc 迁移到Spring Boot
博客地址:https://blog.csdn.net/shang_xs/article/details/86654453
微信公众号来源:https://mp.weixin.qq.com/s?__biz=MzUxMzk4MDc1OQ==&mid=100000061&idx=1&sn=8dd762e1b4b03c4caa31680bb7623eb8&scene=19#wechat_redirect
在Spring Wbe Mvc
中一次请求首先经由DispatcherServlet#doDispatch
开始分发交易
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
//在Spring3.2之后,支持WebAsync异步处理
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
//转换请求为多个部分并获得相应的处理器
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// 找到当前请求对应的handler
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 找到当前请求对应的handler适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
//执行拦截器preHandle
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 反射调用实际执行的handler,返回ModelAndView
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
applyDefaultViewName(processedRequest, mv);
//执行拦截器postHandle
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
//此处主要是使@ExceptionHandler处理起作用
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
//执行拦截器processDispatchResult,当程序正常结束时执行
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// 相当于postHandle 和 afterCompletion
if (mappedHandler != null) {
//该实现在HandlerInterceptorAdapter中也有定义
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
//清除所有请求的处理所对应的资源占用
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
以上是整个请求过程中对应的流程的实现大纲。接下来我们展开细节讨论:
初始化
private void initMultipartResolver(ApplicationContext context) {
try {
this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
...
}
实际执行
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
...
//校验请求信息,返回check结果
return this.multipartResolver.resolveMultipart(request);
}
初始化
private void initHandlerMappings(ApplicationContext context) {
...
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
}
实际执行
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
// 找到当前请求对应的handler
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
初始化
private void initHandlerAdapters(ApplicationContext context) {
...
this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
}
实际执行
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
//找到当前请求对应的handler适配器
return adapter;
...
}
//执行拦截器pre方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
实际执行方法调用
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
主要实现方法
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
//执行方法调用
invocableMethod.invokeAndHandle(webRequest, mavContainer);
//返回ModelAndView
return getModelAndView(mavContainer, modelFactory, webRequest);
}
执行方法
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//执行参数处理和反射调用
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
//处理返回结果
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
调用首先执行参数处理
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
//此处为主要实现,寻找最匹配的参数处理器,并返回处理结果
args[i] = findProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
return args;
}
然后执行反射方法调用
protected Object doInvoke(Object... args) throws Exception {
//设置Accessible
ReflectionUtils.makeAccessible(getBridgedMethod());
//实际调用
return getBridgedMethod().invoke(getBean(), args);
}
执行返回结果处理
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
...
}
获得ModelAndView
private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {
// 返回ModelAndView
return mav;
}
执行拦截器post处理
mappedHandler.applyPostHandle(processedRequest, response, mv);
执行processDispatchResult包括异常处理和视图渲染
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
//获得ModelAndView
mv = ((ModelAndViewDefiningException) exception).getModelAndView();
//执行异常处理
mv = processHandlerException(request, response, handler, exception);
errorView = (mv != null);
if (mv != null && !mv.wasCleared()) {
//渲染视图
render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
else {
logger.trace("No view rendering, null ModelAndView returned.");
}
}
视图解析和渲染
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
String viewName = mv.getViewName();
if (viewName != null) {
// 解析视图名称
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
if (view == null) {
throw new ServletException("");
}
}
else {
//从ModelAndView中获取视图
view = mv.getView();
}
//视图渲染
view.render(mv.getModelInternal(), request, response);
}
最终实现最佳匹配渲染
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);
}
以上所有的源码解析,就是在一次http请求到达,Spring Web Mvc
进行的相应处理,不足之处请批评指正!
博客:https://blog.csdn.net/shang_xs
微信公众号: java界的小学生