这两天梳理了一下 SSM 的配置,做一个小总结
可能有一些不对的地方,如果您发现了什么错误,非常希望能帮忙指出,谢谢
我参考了很多文章,都标明了来源(链接),可能会影响阅读的连贯性,抱歉
1、Tomcat 的角色是什么?
web 服务器、应用服务器、web 容器(Servlet 容器)之间的关系,可以参考刘大的文章:
其中,对于我解惑很重要的一点是(个人的一个理解,事实不一定完全是这样,至少通过这样的理解,可以帮助我弄清楚逻辑):
Tomcat 既可以只做 web 容器也可以既做 web 服务器,又做 web 容器
对于前者,Tomcat 接收其他 web 服务器转发过来的请求,然后调用 servlet 进行处理即可
对于后者,Tomcat 自己接收浏览器发过来的请求(不需要其他 web 服务器中转了),然后调用 servlet 进行处理
2、SpringMVC 中各角色的认识及其相关配置
在搭建 SSM 框架的时候,会有一些配置文件
对于 web.xml 和 spring-web.xml 文件,先弄清楚 SpringMVC 的工作原理图(更准确地说,是流程图),有利于理解这些配置文件中的内容
关于 SpringMVC 的原理图,可以参考以下公众号文章:
其中的一张图是:
其中,需要程序员开发的有两个,一个是 Handler(就是 SSM 中的 Controller 类),另一个是 jsp 文件(就是视图解析器解析的对象)
对于不需要程序员开发的
前端控制器(DispatcherServlet)、处理器映射器(HandlerMapping)、处理器适配器(HandlerAdapter)以及视图解析器(ViewResolver)
我们需要对它们进行配置
其中,前端控制器(DispatcherServlet),配置在 web.xml 文件的 <servlet> 标签中,例如:
<!-- 配置DispatcherServlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置springMVC需要加载的配置文件
spring-dao.xml,spring-service.xml,spring-web.xml
Mybatis - > spring -> springmvc
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-*.xml</param-value>
</init-param>
</servlet> <!-- 配置DispatcherServlet作用范围(或者叫映射范围) -->
<servlet-mapping>
<!-- (与<servlet标签中的<servlet-name>的内容对应>) -->
<servlet-name>dispatcher</servlet-name>
<!-- 默认匹配所有的请求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
处理器映射器(HandlerMapping)、处理器适配器(HandlerAdapter)以及视图解析器(ViewResolver),这三个都在 spring-web.xml 文件中配置,例如:
<!-- 配置SpringMVC --> <!-- 1.开启SpringMVC注解模式 -->
<!-- 简化配置:
自动注册DefaultAnootationHandlerMapping,AnotationMethodHandlerAdapter
该注解确实可以代替映射器和适配器的配置
参考:https://blog.csdn.net/u013310119/article/details/51698347
-->
<mvc:annotation-driven /> <!-- 2.扫描web相关的bean(即,handler,或者说 Controller) --><!-- 和第1点结合起来 -->
<context:component-scan base-package="com.hisen.web" /> <!-- 3.配置jsp相关 视图解析器ViewResolver -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!--
关于第3点,结合实际使用,看看它是怎么发挥作用的
BookController 类中的如下代码
return 一个文件名就行,前缀(路径)和后缀(文件类型)都已经在视图解析器里面配置好了(注:prefix表示前缀,suffix表示后缀)
@RequestMapping(value = "/list", method = RequestMethod.GET)
private String list(Model model) {
List<Book> list = bookService.getList(0, 1000);
model.addAttribute("list", list);
return "list";// WEB-INF/jsp/"list".jsp
}
-->
3、web 容器(servlet 容器)是怎么加载 DispatcherServlet 的?
由第 2 点中的 SpringMVC 工作原理图可知,SpringMVC 的核心是 DispatcherServlet
那么,web 容器(servlet 容器)是怎么加载 DispatcherServlet,来让 SpringMVC 发挥作用呢?
首先,需要强调的一点是,在 JavaWeb 的初始阶段,是没有框架这一说的,程序员一开始是直接使用 servlet 编程的。
而 SpringMVC 中的核心类 DispatcherServlet 本质上也是一个 Servlet
所以,对于 web 容器是怎么加载 DispatcherServlet 的这个问题,可以转化为:
在 JavaWeb 的初始阶段,web 容器是怎么管理 servlet 的?
我觉得可以转化为这个问题:Servlet 的生命周期是什么?参考以下文章即可:
大概的点是:
servlet 有三个主要的方法,init()、service()、destroy()
web 容器初始化时,创建 servlet 实例,并调用其 init() 方法,进行一些初始化操作
web 容器启动后,有请求发过来,web 容器会调用 servlet 的 service() 方法,处理请求
web 容器关闭或者重启时,调用 servlet 的 destroy() 方法,告知 JVM 该 servlet 实例可以被垃圾回收了
回到原来的问题,即,web 容器(servlet 容器)是怎么加载 DispatcherServlet,来让 SpringMVC 发挥作用呢?
DispatcherServlet 配置在 web.xml 文件*,Tomcat 是怎么读取 web.xml 文件的?
可以参考以下文章:
即,在 web 容器启动时,web 容器会去 web.xml 读取相关配置信息(参数配置、监听器、过滤器),并根据 <servlet> 标签的内容创建 DispatcherServlet 实例并初始化(调用 init() 方法)它
4、扩展
在了解 web.xml 文件的时候,我有个疑问,就是:
在 <context-param> 和 <init-param> 中配置信息,有什么不同?
可以参考:
大致意思是:
在 <context-param> 中配置的内容,整个应用都读取
在 <init-param> 中配置的内容,只有特定的 servlet 可以读取(该标签是 <servlet> 的字标签)
那么,spring-web.xml 和 spring-dao.xml 等配置文件的路径在哪个标签中配置呢?
我的结论:
都可以
理由:
根据 SpringMVC 工作原理图,只需要在 DispatchServlet 创建的时候,能读取到相关信息就行了