SpringMVC 源码分析

SpringMVC的运行原理图

 

SpringMVC 源码分析

 

DispatcherServlet:
DispatcherServlet 继承结构

 

 

HttpServletBean
HttpServletBean 覆写了 init 方法,主要做一些初始化的工作,将 web.xml 中配置的参数设置到 Servlet 中。比如 servlet 标签的子标签 init-param 标签中配置的参数

 

ServletConfigPropertyValues
ServletConfigPropertyValues HttpServletBean 的静态内部类。在其构造方法中通过传递的 ServletConfig 对象对 web.xml 文件中的 DispatcherServlet 节点中的参数进行解析处理。

 

BeanWrapper bw=PropertyAccessorFactory.forBeanPropertyAccess(this)
HttpServletBean 类型转换为 BeanWrapper 类型,从而能对 init-parameter 的值进行注入。

 

bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()))
注册自定义属性编辑器,遇到 Resource 类型的属性将会使用 ResourceEditor 进行解析

 

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

 

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

 

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

 

 

FrameworkServlet
Servlet 上下文与 Spring 容器上下文关联。其实也就是初始化 FrameworkServlet 的属性 webApplicationContext ,这个属性代表 SpringMVC 上下文对象 , 实际类型 ConfigurableWebApplicationContext 。如果项目中用到 spring 了那么它有个父容器,既 web.xml 中配置的 ContextLoaderListener 监听器初始化的容器上下文

 

this.webApplicationContext =initWebApplicationContext():
可以看到 , 最重要的就是 this.webApplicationContext = initWebApplicationContext();这段代码 , 这个方法的作用是创建或刷新 WebApplicationContext 实例。如果项目中使用 到了 spring ,则进行父子容器关联。

 

initWebApplicationContext() 方法:

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

 

如果没有在 web.mxl 文件中配置 Listener 那么此时 webApplicationContext为 空 则 去 ServletContext 中 根 据 attrname 查 找 。 如 果 为 找 到 , 执 行 createWebApplicationContext 方法来创建 SpringMVC 的容器。

 

createWebApplicationContext(rootContext)

 

createWebApplicationContext(ApplicationContext parent)

 

configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext  wac)

 

 

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

等等。。。。。。。

 

DispatcherServlet
ContextRefreshListener

 

onRefresh(ApplicationContext context)

 

initStrategies(ApplicationContext context)
初始化 SpringMVC 其他组件:如多部件解析器、处理器映射器、处理器适配器、视图 解析器等。

 

HandlerMapping 接口
初始化 HandlerMapping
initStrategies

 

 

initHandlerMappings

 

HandlerMapping 接口介绍
作用是根据当前请求的找到对应的 Handler HandlerMethod(Controller 中的方法 ) 、Controller 对象) ,并将 Handler 与一堆 HandlerInterceptor ( 拦 截 器 ) 封 装 到 HandlerExecutionChain 对象中。在 HandlerMapping 接口的内部只有一个方法:
HandlerExecutionChain getHandler(HttpServletRequest request);

 

HandlerMapping 接口实现类
HandlerMapping 实现类有两个分支,分别继承自 AbstractHandlerMethodMapping (得到 HandlerMethod )和 AbstractUrlHandlerMapping (得到 Controller t ),它们又统一继承于 AbstractHandlerMapping

 

 

AbstractHandlerMapping 抽象类
它实现了 HandlerMapping 接口中的 getHandler() 方法

 

AbstractHandlerMethodMapping
AbstractHandlerMethodMapping 这个分支获取的 Handler 的类型是 HandlerMethod ,即这个 Handler 是一个方法,它保存了方法的信息(如 Method ),这样一个 Controller 就可 以处理多个请求了。

上 述 代 码 中 lookupHandlerMethod() 方 法 主 要 工 作 是 在 Map<T, HandlerMethod> handlerMethods 中找到 HandlerMethod ,这里的 T HandlerMappingInfo ,它封装了 @RequestMapping 注解中的信息。

 

 

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

 

Debug 走读 HandlerMapping

 

 

HandlerAdapter 接口
SpringMVC 中使用适配器模式来解决不同的 Handler 的执行。根据 Handler 来找到支持它的 HandlerAdapter ,通过 HandlerAdapter 执行这个 Handler 得到 ModelAndView 象。

 

接口中的抽象方法
boolean supports(Object handler); 判断是否支持传入的 HandlerModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) 用来使用 Handler 处理请求
long getLastModified(HttpServletRequest request, Object handler); 用 来 获 取 资 料 的Last-Modified

 

 HandlerAdapter 继承结构

 

AbstractHandlerMethodAdapter 抽象类

 

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

 

handleInternal 方法
handlerInternal 方法中通过调用 invokeHandleMethod 方法执行 HandlerMethod 并返回一个 ModelAndView

 

invokeHandleMethod 方法

 

HttpRequestHandlerAdapter
HttpRequestHandlerAdapter 。是 HttpRequestHandler 的适配器可以执行HttpRequestHandler 类型的 Handler 。其实就是 Controller 中的 handleRequest 方法

 

SimpleControllerHandlerAdapter
SimpleControllerHandlerAdapter Controller 实现类的适配器类,其本质也是执行Controller 中的 handleRequest 方法。

 

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

 

 

DispatcherServlet 中初始化处理器适配器
在配置文件中配置 <mvc:annotation-driven />

 

未在配置文件中配置 <mvc:annotation-driven />
[org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter@508cddf9,
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter@688a3991, org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter@6f15d 959]

 

ViewResolver 接口
根据视图的名称将其解析为 View 类型的视图,如通过 ModelAndView 中的视图名称将其解析成 View View 是用来渲染页面的,也就是将 Model 填入模板中,生成 html 其他格式的文件。
 
 
 
接口中抽象方法
 
View resolveViewName(String viewName, Locale locale) throws Exception;
 
 
ViewResolver 接口结构
 
 
 
 
 
 
AbstractCachingViewResolver 抽象类
AbstractCachingViewResolver 是带有缓存的 ViewResolver ,它每次解析时先从缓存里查找,如果找到视图就返回,没有就创建新的视图,且创建新视图的方法由其子类实现。
 
 
resolveViewName 方法
 
 
 
 
createView 方法
通过调用不同的子类中的 loadView 来指定不同视图解析器处理视图。
 
 
 
 
ResourceBundleViewResolver
ResourceBundleViewResolver 根据 views.properties 文件来解析视图,这个文件应位于classpath 路径下
 
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver"> 
    <!-- 设定属性文件名为 views --> 
    <property name="basename" value="views">
    </property>
 </bean>
user.(class)=org.springframework.web.servlet.view.JstlView
user.url=/WEB-INF/jsp/user.jsp
ModelAndView mv = new ModelAndView("user","msg", "aaa");

 
 
XmlViewResolver
 
<bean class="org.springframework.web.servlet.view.XmlViewResolver">
  <property name="location"> 
  <value>spring-views.xml</value> 
  </property> 
</bean>
<bean id="internalResource" class="org.springframework.web.servlet.view.JstlView">
  <property name="url" value="/index.jsp" /> 
</bean>
ModelAndView mv = new ModelAndView("internalResource","msg", "aaa");

 
 
UrlBasedViewResolver
UrlBasedViewResolver 提供了拼接 URL 的方式来解析视图,通过 prefix 属性拼接一个前缀,通过 suffix 属性拼接一个后缀,就得到了视图的 URL 。还可以加入 redirect: forword: 前缀,使用 redirect: 前缀会调用 HttpServletResponse 对象 sendRedirect() 方法 进行重定向,使用 forword: 前缀会利用 RequestDispatcher forword 方式跳转到指定的地 址。另外,使用时还要指定 viewClass 属性,表示要解析成哪种 View
 
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"> 
   <property name="prefix" value="/WEB-INF/" /> 
   <property name="suffix" value=".jsp" /> 
   <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView" /> 
</bean>

 
 
 
 
InternalResourceViewResolver
 
InternalResourceViewResolver UrlBasedViewResolver 的 子 类 , 将InternalResourceView 作为默认的 View 类,但如果当前 classpath 中有 jstl jar 包时则 使用 JstlView 作为 view 来渲染。
 
 
UrlBasedViewResolver
 
 
 
InternalResourceViewResolver
 
 
 
 
 
View 接口
视图渲染器,在该接口中定义了渲染视图的抽象方法。
何为渲染:所谓渲染其实就是将 Model 中的数据放到 HttpServletRequest 中传递 jsp
void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
 
 
 
接口结构
 
 

 

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

 

ViewResolver
DispatcherServlet 初始化视图解析器

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值