springmvc项目在启动完成之后执行一次方法_SpringMVC源码分析

一 SpringMVC运行原理

9ebccbbfac9496de487f54b6660640d8.png

二 SpingMVC源码分析

1 DispatcherServlet

1.1 DispatcherServlet继承结构

e391d4567bf155e4cb4c6ba556c8e1e6.png

ServletConfig对象获取Init标签中的配置信息

1.1.1 HttpServletBean

HttpServletBean复习了init方法,主要做一些初始化的工作麻将web.xml中配置的参数

设置到Servlet中。比如servlet标签中的子标签init-param标签中配置的参数

40243c6cbd0641c213714e9a3c17f538.png

1.1.1.1 ServletConfigPropertyValues

ServletConfigPropertyValues是HttpServletBean的静态内部类。在其构造方法中通

过传递的ServletConfig对象对web.xml文件中的DispatcherServlet节点中的参数及

及逆行解析处理

7542feb2a0c5b6fcad7647e740bfb23a.png

1.1.1.2 BeanWrapper bw =PropertyAccessorFactory.forBeanPropertyAccess(this):

将 HttpServletBean 类型转换为 BeanWrapper 类型,从而能对 init-parameter 的

值进行注入。

1.1.1.3 bw.registerCustomEditor(Resource.class,

newResourceEditor(resourceLoader,getEnvironment())):

注册自定义属性编辑器,遇到 Resource 类型的属性将会使用 ResourceEditor 进行解析

1.1.1.4 initBeanWrapper(bw):该方法并未做什么,为了留给子类覆盖。

1.1.1.5 bw.setPropertyValues(pvs,true): 设置 DispatcherServlet 属性

1.1.1.6 initServletBean(): 调用在 FrameworkServlet 中覆盖的该方法

* 当spingmvc启动时会调用init方法获取inint标签中属性的值,将值封装到

ProperValues中

1.1.2 FrameworkServlet

将 Servlet 上下文与 Spring 容器上下文关联。其实也就是初始化 FrameworkServlet

的属 性webApplicationContext , 这 个 属 性 代 表 SpringMVC 上 下 文 对 象 , 实

际 类 型ConfigurableWebApplicationContext。如果项目中用到spring了那么它有个

父容器,既web.xml 中配置的 ContextLoaderListener 监听器初始化的容器上下文。

1b2d5a2e8031afa80f45ca7eac5da74f.png

1.1.2.1 this.webApplicationContext = initWebApplicationContext():

可以看到,最重要的就是

this.webApplicationContext=initWebApplicationContext(); 这段代码,这个方法的

作用是创建或刷新 WebApplicationContext 实例。如果项目中使用 到了 spring,则

进行父子容器关联。

1.1.2.2 initWebApplicationContext()方法:

0d17edbb13d4c3433cfe7a4ed232c7b4.png

b945b95f401dba7d6d8db3edef01112f.png

如果项目中使用 spring 框架,并且在 web.xml 文件中配置了 Listener 来启动 spring。那 么在监 听器中 spring 会创建 WebApplicationContext 容器。 此时会将 该容器转换 为 ConfigurableWebApplicationContext 即 SpringMVC 容器。

3b18fae2d443d0ed47dbfecd922fe5a9.png

如果没有在 web.mxl 文件中配置 Listener 那么此时 webApplicationContext 为 空 则 去

ServletContext 中 根 据 attrname 查 找 。 如 果 为 找 到 , 执 行

createWebApplicationContext 方法来创建 SpringMVC 的容器。

1.1.2.3 createWebApplicationContext(rootContext):

1fb254bc4b3914dbc0f0fbff23ed99a0.png

1.1.2.4 createWebApplicationContext(ApplicationContext parent)

cd009ad470bfee018bb757535672414a.png

1.1.2.5 configureAndRefreshWebApplicationContext

(ConfigurableWebApplicationContextwac):

b4dc2cfd5f7533b46904bd904aef9aae.png

1.1.2.6 refresh():

解析配置文件初始化 SpringMVC 的 IOC 容器环境。 解析 springmvc 配置文件:

初始化所有的bean对象

421e47fb0f00557c0efa98f0d7fd9b23.png

解析命名空间

0c3027775240fbf3fc6afb2c54ba3695.png

1.1.3DispatcherServlet

1.1.3.1 ContextRefreshListener

5973c3f43febae96feacf03fcb4fe910.png

1.1.3.2 onRefresh(ApplicationContextcontext):

1.1.3.3 initStrategies(ApplicationContextcontext): 初始化 SpringMVC 其他组件:如多

部件解析器、处理器映射器、处理器适配器、视图解析器等。

8cc3cc93ce09dca0e11c13ba408bc00b.png

2 HandlerMapping接口

2.1 初始化HandlerMapping接口

2.1.1initStrategies

23ac63e44abb2376267af399fc345a5a.png

2.1.2initHandlerMappings

d0e1cb276c37250d75eddd8f4c12aac6.png

2.2HandlerMapping 接口介绍

作用是根据当前请求的找到对应的Handler(HandlerMethod(Controller 中的方法)、

Controller 对 象 ),并将Hanler与一堆HandlerInterceptor (拦截器)封装到

HandlerExecutionChain 对象中。在HandlerMapping接口的内部只有一个方法

HandlerExecutionChaingetHandler(HttpServletRequestrequest);

2.3HandlerMapping 接口实现类

HandlerMapping 实现类有两个分支,分别继承自

AbstractHandlerMethodMapping(得 到 HandlerMethod)和

AbstractUrlHandlerMapping(得到 Controllert),它们又统一继承于

AbstractHandlerMapping。

1735cca1ad2b09fd27e4c88c02f2b029.png

2.3.1 AbstractHandlerMapping抽象类

它实现了 HandlerMapping 接口中的 getHandler() 方法

01e5efb6f883970e9887b0b47956a91d.png

2.3.1.1 AbstractHandlerMethodMapping

AbstractHandlerMethodMapping 这个分支获取的 Handler 的类型是

HandlerMethod,即 这个Handler 是一个方法,它保存了方法的信息(如

Method),这样一个 Controller 就可 以处理多个请求了。

64edeaf47e74fbc33a914368e8e655ce.png

上述代码中 lookupHandlerMethod() 方法主要工作是在 Map<T, HandlerMethod>

handlerMethods 中找到 HandlerMethod,这里的 T 是 HandlerMappingInfo,它

封装了 @RequestMapping 注解中的信息(url),HandlerMethodshurl对应的方法。

2.3.1.2 AbstractUrlHandlerMapping 抽象类

AbstractUrlHandlerMapping 这个分支获取的 Handler 的类型实际就是一个

Controller类。

a458f85a731ad1a028cd4443f7aa8b5c.png

e9c378fc33df5f065c048fa9268ea999.png

3 HandlerAdapter 接口

SpringMVC 中使用适配器模式来解决不同的 Handler 的执行。根据 Handler 来找到支

持它的HandlerAdapter,通过 HandlerAdapter 执行这个 Handler 得到

ModelAndView 对 象。

3.1接口中的抽象方法

booleansupports(Objecthandler); 判断是否支持传入的 Handler ModelAndView

handle(HttpServletRequest request, HttpServletResponse response, Object

handler) :用来使用 Handler 处理请求

long getLastModified(HttpServletRequest request, Object handler); 用 来 获 取 资

料 的 Last-Modified 值

3.2 HandlerAdapter继承结构

23b20d9a2e6d3d90ef4ae198a29f09df.png

3.3 AbstractHandlerMethodAdapter 抽象类

利用 RequestMappingHandlerMapping 获取的 Handler 是 HadnlerMethod 类型,

它代 表 Controller 里要执行的方法。handlerInternal 是子类

RequestMappingHandlerAdapter 中的 方法。

317ae6e12b467e467498fd9de8e4f73e.png

3.4 RequestMappingHandlerAdapter 类

RequestMappingHandlerAdapter 实际就是执行@RequestMapping 注解的方法

3.4.1 handleInternal 方法

在 handlerInternal 方法中通过调用 invokeHandleMethod 方法执行

HandlerMethod 并返回 一个 ModelAndView。

02ad7b501bfa7a291a5dac022c0ee518.png

3.4.2invokeHandleMethod 方法

926da890c5e646f9eed4d6abf1d5514d.png

3.5 HttpRequestHandlerAdapter 类

HttpRequestHandlerAdapter 。 是 HttpRequestHandler 的 适 配 器 可 以 执 行

HttpRequestHandler 类型的 Handler。其实就是 Controller 中的 handleRequest 方法

bb278e7faaecacc1547085fdd2d3c690.png

3.6 SimpleControllerHandlerAdapter 类

SimpleControllerHandlerAdapter 是 Controller 实现类的适配器类,其本质也是执行

Controller 中的 handleRequest 方法。

261f0e1b435fe1a87b733b06f8177223.png

3.7 SimpleServletHandlerAdapter 类

SimpleServletHandlerAdapter 其实是一个 Servlet 的适配器,其最终执行的方法是

Servlet 的 service 方法、

8335629fa44ac66df6ff6ad85a00ede1.png

3.8Debug 走读 DispatcherServlet 中初始化处理器适配器

3.8.1在配置文件中配置<mvc:annotation-driven/>

{org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerA

dapter#0=org.springframework.web.servlet.mvc.method.annotation.RequestMapping

HandlerAdapter@4e afea11, org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter=org.springframew

ork.we b.servlet.mvc.HttpRequestHandlerAdapter@1a4d6190, org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter=org.springfra

mewor k.web.servlet.mvc.SimpleControllerHandlerAdapter@710d6556}

3.8.2未在配置文件中配置<mvc:annotation-driven/>

[org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter@508cddf9,

org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter@688a3991,

org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

@6f15d959]

4 ViewResolver 接口

根据视图的名称将其解析为 View 类型的视图,如通过 ModelAndView 中的视图名称 将

其解析成 View,View 是用来渲染页面的,也就是将 Model 填入模板中,生成 html 或

其他格式的文件。

4.1接口中抽象方法

ViewresolveViewName(StringviewName,Localelocale)throwsException;

52eb70c49ff0b874fc8a5315b0c71e98.png

4.3AbstractCachingViewResolver 抽象类

AbstractCachingViewResolver 是带有缓存的 ViewResolver,它每次解析时先从缓存里

查 找,如果找到视图就返回,没有就创建新的视图,且创建新视图的方法由其子类实现。

e42944afbd447d8c69fa27c93c61eb33.png

4.3.2 createView方法

通过调用不同的子类中的 loadView 来指定不同视图解析器处理视图。

3e5d1682e10959694d555f0298ee6084.png

4.4ResourceBundleViewResolver 类

ResourceBundleViewResolver 根据 views.properties 文件来解析视图,这个文件应位于

classpath 路径下

23c3230578ae5e03b167a6c0e9ef37ed.png

4.5XmlViewResolver 类

XmlViewResolver 根据 xml 文件来解析视图

ef38701e86db9965429d58c6c8b1a823.png

4.6UrlBasedViewResolver 类

UrlBasedViewResolver 提供了拼接 URL 的方式来解析视图,通过 prefix 属性拼接一 个

前缀,通过 suffix 属性拼接一个后缀,就得到了视图的 URL。还可以加入 redirect: 与、

forword: 前缀,使用 redirect: 前缀会调用 HttpServletResponse 对象的

sendRedirect() 方法 进行重定向,使用 forword: 前缀会利用 RequestDispatcher 的

forword 方式跳转到指定的地 址。另外,使用时还要指定 viewClass 属性,表示要解析

成哪种 View。

5a9dd88c7e37a53b2853bfbfc14b2075.png

3d836a39fe3e41c985c9fd76d712a012.png

4.7InternalResourceViewResolver 类

InternalResourceViewResolver 是 UrlBasedViewResolver 的 子 类 , 将

InternalResourceView 作为默认的 View 类,但如果当前 classpath 中有 jstl 的 jar 包

时则 使用 JstlView 作为 view 来渲染。

4.7.1 UrlBasedViewResolver 类

b46499dcadbea83b1045e00f3c88a89a.png

4.7.2InternalResourceViewResolver 类

faf0ad41a87a9cde5ba938656bbb22e5.png

5 View接口

视图渲染器,在该接口中定义了渲染视图的抽象方法。 何为渲染:所谓渲染其实就是将

Model 中的数据放到 HttpServletRequest 中传递 jsp。

void render(Map<String, ?> model, HttpServletRequest request,

HttpServletResponse response)throwsException;

5.1 结构结构

40e0b4724f34731c084b74cf78d87668.png

5.2 InternalResourceView 类

继承自 AbstractUrlBasedView 抽象类的类,表示 JSP 视图

5.3Debug 走读 ViewResolver

5.3.1DispatcherServlet 初始化视图解析器

709bd5256f08f97155e2518521b4d476.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值