由于下周二要给公司实习生进行JavaWeb基础的培训,所以今天边写ppt边学习了servlet基础知识,同时自己动手写了培训中要使用的小例子。在这过程中不得不感慨一下spring框架给后端开发带来的便利。这也是目前很多人在学习java时都从spring框架学起的原因。

但这会带来很多的问题,首先是很多人在开发过程中只会按照公司现有框架固定的代码结构进行开发,代码也都是CURD来回复制。导致很多人对框架的原理不清晰,很多在公司工作两三年的人可能都不能说出框架的基本原理是什么。

其次是在开发过程中如果只会CURD那么在遇到一些难题时就无从下手。

在写servlet例子的时候了解了一个请求如何到后台和传参,再对比使用的SpringMVC框架,为什么SpringMVC框架就可以不在web.xml中配置各个servlet就实现了请求的处理。这里就不得不提DispatchSevlet了。使用SpringMVC框架时需要在web.xml中配置DispatchSevlet。那可以猜想是不是使用DispatchSevlet来接收所有的请求,然后根据url来找到写有注解RequestMapping的方法,同时将请求中的参数进行特定的预处理,这样才能直接传递到方法的参数中,之后后台业务处理完将结果返回给DispatchSevlet,再经过一系列的处理返回给前端。

以下是DispatchSevlet具体的请求过程和部分源码,以下内容转自 https://blog.csdn.net/ChaoticNg/article/details/88082046

1、Spring mvc介绍

SpringMVC框架是以请求为驱动,围绕Servlet设计,将请求发给控制器,然后通过模型对象,分派器来展示请求结果视图。其中核心类是DispatcherServlet,它是一个Servlet,顶层是实现的Servlet接口。

2、SpringMVC使用

需要在web.xml中配置DispatcherServlet。并且需要配置spring监听器ContextLoaderListener


<listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>        
<servlet>
	<servlet-name>springmvc</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<!-- 如果不设置init-param标签,则必须在/WEB-INF/下创建xxx-servlet.xml文件,其中xxx是servlet-name中配置的名称。  -->
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring/springmvc-servlet.xml</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>springmvc</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>

3、SpringMVC运行原理

如图所示:

DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自己定义,把拦截下来的请求,依据相应的规则分发到目标Controller来处理,是配置spring MVC的第一步。

DispatcherServlet是前端控制器设计模式的实现,提供Spring Web MVC的集中访问点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而可以获得Spring的所有好处。

  • HandlerMapping是个接口,里面就只有一个方法getHandler,源码如下:
  • spring项目启动的时候会扫描包,专门有个map用来存储controller类的(key是@RequestMapping里面的value),这个getHandler方法就是根据这个value找到这个类对象。
     
  • HandlerAdapter里面有个方法handle,参数需要一个handler,返回值就是ModelAndView,model是键值对形式的参数啦,view就是返回的那个String,比如:/login,在SpringMVC配置文件里面不是配置了视图解析器么,完了还配置了前缀和后缀,前缀是**/jsp/后缀是.jsp还记得么,完了万一找不到你写的那个返回视图还会报404,这里就是原因。
  • 下面来看看ViewResolver,这哥们也是个接口,里面就一个方法,resolveViewName,所以说源码写得好,光看名字就知道是干啥的,参数一个name一个locale,就是根据名字和前后缀就能找到那个jsp了,View也是个接口有很多实现类,配置文件里面不是要注明解析类么,解析类就是View的子类,找到jsp把里面的东东解析成浏览器能认识的东东。
  • 最后返回给DispatchServlet,这个类自己做后面的操作,也就是渲染view再返回给浏览器,这里DispatchServlet类做了一个判断,处理返回的不是view而是其他的类型的情况,比如移动端请求一些数据,如果不是view那么就没有viewResolver什么事了,跳过它往下执行,如果是view就会进入到render方法中。
  • 最终会执行到AbstractView类中的render方法,我们来看看这哥们干了啥事:
  • 最后是个renderMergedOutputModel方法,这个方法的实现类是AbstractView的子类,叫InternalResourceView,这个类又调用父类AbstractView的exposeModelAsRequestAttributes方法,这个方法就是把model注入到request的attribute中,这里你肯定要问,为嘛调来调去呢,不麻烦么,我来简单解释一下,根据java设计理论,顶层肯定是接口,抽象类实现这个接口,并可以添加一些通用的方法,这个exposeModelAsRequestAttributes就是起到这个作用。
     
  • 最后一步,请看下图:
  • forward是不是很熟悉,这不是服务端发起的请求么,好了,以上,就是这样。

By xbingo

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注