在有关借助maven构筑ssm的网志,他们一起来深入探讨下问的最多的难题中,我遗留下来了两个难题:Spring mvc是何时、何地、怎样将Model中的特性存取到别的返回值,这儿的返回值指的是Servlet的五大返回值;不介绍难题大背景的能转过头去看一看我的上篇昌明。

明晰的答疑就要放在最终,在答疑难题以后,我先和我们一起来捋一捋Spring mvc的组织工作基本原理。专业术语太少说,已经开始他们谜样的历险之旅!

应用领域实例

在讲组织工作基本原理以后,他们先看两个单纯的spring mvc(ssm)实例,和同时实现的效用

工程建设标识符门牌号:ssm-web

自动草稿

工程建设内部结构与效用如上右图,他们不做过多的探求,他们轻装上阵往上看第一集的重点项目

组织工作基本原理

预备 – 天然资源的读取与调用

1、DispatcherServlet 动态调用

DispatcherServlet如下表所示动态块

static {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException(“Could not load DispatcherServlet.properties: ” ex.getMessage());
}
}

这儿会将DispatcherServlet.properties中的内容读取到DispatcherServlet的特性:private static final Properties defaultStrategies中,DispatcherServlet.properties内容如下表所示

Default implementation classes for DispatcherServlets strategy interfaces.
Used as fallback when no matching beans are found in the DispatcherServlet context.
Not meant to be customized by application developers.
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

指定了DispatcherServlet策略接口的默认同时实现,后续DispatcherServlet调用策略的时候会用到

2、interceptor定义的读取

spring启动过程中会调用InterceptorsBeanDefinitionParser的parse方法来解析出他们自定义的interceptor定义,封装成MappedInterceptor类型的bean定义,并放在spring容器中;他们能单纯的认为spring容器中已经存在了他们自定义的interceptor的bean定义

3、DispatcherServlet调用策略:initStrategies

DispatcherServlet的继承图如下表所示

自动草稿

DispatcherServlet是两个Servlet,tomcat启动过程中会调用其init方法,一串的调用后,会调用DispatcherServlet的initStrategies方法

protected void initStrategies(ApplicationContext context) {

initMultipartResolver(context);

initLocaleResolver(context);

initThemeResolver(context);

initHandlerMappings(context);

initHandlerAdapters(context);

initHandlerExceptionResolvers(context);

initRequestToViewNameTranslator(context);

initViewResolvers(context);

initFlashMapManager(context);

}

实例化步骤1中的默认同时实现,并填充到DispatcherServlet各个特性值中

4、DefaultAnnotationHandlerMapping的拦截器调用

DispatcherServlet.properties种指定了两个默认的HandlerMapping:BeanNameUrlHandlerMapping、DefaultAnnotationHandlerMapping,这两者的类继承图如下表所示(他们暂时只关注DefaultAnnotationHandlerMapping)

自动草稿

DefaultAnnotationHandlerMapping间接同时实现了ApplicationContextAware,那么在DefaultAnnotationHandlerMapping实例调用过程中,会调用setApplicationContext(ApplicationContext applicationContext)方法,一串调用后,会来到AbstractUrlHandlerMapping的initApplicationContext()

@Override
protected void initApplicationContext() throws BeansException {
extendInterceptors(this.interceptors);
detectMappedInterceptors(this.mappedInterceptors);
initInterceptors();
}

调用了DefaultAnnotationHandlerMapping的拦截器:interceptor

他们来看下具体的调用过程,看一看上面的顺序是否只是我个人的臆想?

自动草稿

能看到,调用顺序就是他们上面说的,不是我个人的意淫;此时的DefaultAnnotationHandlerMapping他们自定义的MyInterceptor。调用过程他们需要关注的就是上述这些,下面他们一起看一看具体请求的过程

请求的处理

请求从servlet的service已经开始,一路到DispatcherServlet的doDispatch,如下表所示图

自动草稿

/**
* Process the actual dispatching to the handler. 将请求分发到具体的handler,也就是他们的controller
*

The handler will be obtained by applying the servlets HandlerMappings in order.
* The HandlerAdapter will be obtained by querying the servlets installed HandlerAdapters
* to find the first that supports the handler class.
*

All HTTP methods are handled by this method. Its up to HandlerAdapters or handlers
* themselves to decide which methods are acceptable.
* @param request current HTTP request
* @param response current HTTP response
* @throws Exception in case of any kind of processing failure
*/
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = processedRequest != request;
// Determine handler for the current request. 决定别的handler来处理当前的请求
// mappedHandler是由handler和interceptor集合组成的两个执行链,有点类似FilterChain
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// Determine handler adapter for the current request. 决定别的adapter来处理当前的请求
// handlerMapping是找出适配的handler,而真正回调handler的是adapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = “GET”.equals(method);
if (isGet || “HEAD”.equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
String requestUri = urlPathHelper.getRequestUri(request);
logger.debug(“Last-Modified value for [” requestUri “] is: ” lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified)

1.本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2.分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3.不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4.本站提供的源码、模板、插件等其他资源,都不包含技术服务请大家谅解!
5.如有链接无法下载或失效,请联系管理员处理!
6.本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!