Dev*_*abc 2 java spring servlets spring-mvc spring-boot
(我已经知道答案,但因为我经常发现自己重新寻找答案,所以我将其发布在这里作为我自己和其他人的文档。Stackoverflow鼓励这样做。)
许多 Servlet 开发人员已经阅读了“Head First Serlet & JSP”一书,以参加“Web 组件开发人员认证考试”或只是为了学习 Servlet。但是这本书自 2009 年以来就没有更新过,并且只涵盖了 Servlet 2.4。从那以后很多事情改变了。当前最新版本是4.0。发生变化的事情之一是 servlet Web 应用程序的启动过程,这会使启动过程中发生的情况以及 Web 应用程序如何初始化变得不清楚。
在 Servlet 2.4 及更低版本中,web.xml 用于完全配置 Web 应用程序。但是更高版本似乎有其他方式来配置Web应用程序,无需触及web.xml,也无需注解。例如,作为 .jar 文件提供的 Web 框架能够以某种方式挂钩到 Servlet 容器并添加 url 映射。
这个机制是如何运作的?
在 Servlet 2.4(2003 年 11 月)中,servlet 容器(例如 Tomcat 和 Jetty)通过查找文件WEB-INF/web.xml(部署描述符)来简单地启动 Web 应用程序。文件 web.xml 包含对 servlet、过滤器和侦听器的引用,以及它们关联的 url 模式和参数。使用 web.xml,servlet 容器确切地知道在哪里可以找到所有内容以及如何配置它们。
从 Servlet 3.0(2009 年 12 月)开始,web.xml 是可选的,您也可以使用注释或编程配置来代替。
注释使用起来更简单。它们都位于javax.servlet.annotation包,并允许您注释与@一个servlet WebServlet,用@过滤网页过滤,并用@监听器WebListener。然后,服务器容器将自动查找并检测这些类。然而,注解提供的配置特性比 web.xml 和编程配置少。
本文进一步关注如何配置程序化配置以及它如何启动 Spring MVC。它比注解稍微复杂一些,但确实让您和框架设计人员能够更好地控制启动过程。
如果您想使用 Servlet 3.0 版之前的 Web 框架,则必须将 servlet 或过滤器添加到您的 web.xml 并从那里配置该框架。在此初始化之后,您可以开始编写 Web 框架已知的类(通常是非 Servlet 类)来创建 Web 应用程序。
从 Servlet 3.0 开始,系统是模块化的。这允许框架和库设计者初始化 servlet 容器,而无需通过 web.xml 配置框架。您可以立即开始编写特定于 Web 框架的类来创建 Web 应用程序,而无需接触 Servlet 类。(也可以在 Servlet 3.0 中创建您自己的 web.xml 并仍然让框架进行框架的初始化,而无需在 web.xml 中定义它。)
启动时,Servlet 容器首先查找位于 的部署描述符WEB-INF/web.xml。如果此文件的metadata-complete属性设置为 false,或者根本未定义,则容器还将搜索带注释的类,例如 @WebServlet。
除了查找 web.xml 和带注释的类,从 Servlet 3.0 开始,容器还将查找META-INF/web-fragment.xml位于WEB-INF/lib目录中的 .jar 文件中的文件。
文件 web-fragment.xml 是一个web 片段,它是(引用自Java Servlet 规范)
Web 应用程序的逻辑分区,使得 Web 应用程序中使用的框架可以定义所有工件,而无需要求开发人员在 web.xml 中编辑或添加信息。它可以包含 web.xml 描述符使用的几乎所有相同元素。然而,描述符的顶级元素必须是 web-fragment 并且相应的描述符文件必须被称为 web-fragment.xml。web-fragment.xml 和 web.xml 之间的排序相关元素也不同
web-fragment.xml 的内容与 web.xml 类似,但使用web-fragment根元素而不是web-app元素:
<web-fragment xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
https://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
version="3.0">
<filter>
<filter-name>FrameworkFilter</filter-name>
<filter-class>framework.FrameworkFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>FrameworkFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-fragment>
Run Code Online (Sandbox Code Playgroud)
可以使用<absolute-ordering>和配置加载单个 web.xml 和多个 web-fragment.xml 文件的确切顺序<ordering>。
除了 Web 片段之外,还有一种编程方法来划分 Web 应用程序:通过编写接口的实现 javax.servlet.ServletContainerInitializer。ServletContainerInitializer 提供对 的访问ServletContext,其中包含以编程方式添加 servlet、过滤器和侦听器的方法。要使用ServletContainerInitializer,它必须在位于META-INF/services/javax.servlet.ServletContainerInitializer. 此文件的内容必须是实现类的完全限定路径。
尽管 Spring MVC 确实包含web-fragment.xml,但它没有定义任何 servlet、过滤器或侦听器。Spring 使用该META-INF/services/javax.servlet.ServletContainerInitializer文件来引用它自己的 ServletContainerInitializer 实现类,即类SpringServletContainerInitializer.
SpringServletContainerInitializer 是一个 ServletContainerInitializer,所以它在启动时接收一个 ServletContext。SpringServletContainerInitializer 的目标是将 servletContext 传递给对开发人员更友好的WebApplicationInitializer,以便您可以添加 servlet,例如 Springs DispatcherServlet,它是将传入请求定向到其他控制器的前端控制器。(有关如何将 DispatcherServlet 配置到 Spring,请参阅spring-framework-reference。)
Spring MVC 没有提供 WebApplicationInitializer 的具体实现,只有一些抽象类,以便您可以控制启动过程。在 Spring Boot 的情况下,提供了一个具体的实现:SpringApplicationWebApplicationInitializer减少样板代码的数量。
关于 Servlet 容器启动过程的详细描述,可以在官方Java Servlet 规范中找到。有关 Spring MVC 的更多信息可以在Spring Framework 参考中找到。
| 归档时间: |
|
| 查看次数: |
464 次 |
| 最近记录: |