(我已经知道答案了,但是因为我经常发现自己正在寻找答案,所以我在这里将其发布为自己和其他人的文档。在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模式和参数。servlet容器使用web.xml确切地知道在哪里可以找到所有内容以及如何配置它们。
从Servlet 3.0(2009年12月)开始,web.xml是可选的,因此您也可以使用注释或编程配置。
注释使用起来更简单。它们都位于javax.servlet.annotation包,并允许您注释与@一个servlet WebServlet,用@过滤网页过滤,并用@监听器WebListener。然后,server容器将自动查找并检测这些类。但是,注解提供的配置功能少于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。
从Servlet 3.0开始,除了寻找web.xml和带注释的类之外,容器还将META-INF/web-fragment.xml
在WEB-INF/lib
目录中的.jar文件中寻找文件。
文件web-fragment.xml是一个Web片段,它是(来自Java Servlet Specification的引号)
Web应用程序的逻辑分区,使得Web应用程序内使用的框架可以定义所有工件,而无需要求开发人员在web.xml中编辑或添加信息。它几乎可以包含web.xml描述符使用的所有相同元素。但是,描述符的顶层元素必须是web-fragment,相应的描述符文件必须称为web-fragment.xml。与订购相关的元素在web-fragment.xml和web.xml之间也有所不同
web-fragment.xml的内容类似于web.xml,但是具有一个web-fragment
root元素而不是web-app
element:
<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>
可以使用<absolute-ordering>
和来配置单个web.xml和多个web-fragment.xml文件的确切加载顺序<ordering>
。
除了Web片段之外,还有一种编程方法可以对Web应用程序进行分区:通过编写interface的实现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
减少样板代码的数量。
可以在官方Java Servlet规范中找到有关Servlet容器启动过程如何正确工作的详细说明。有关Spring MVC的更多信息,请参见Spring Framework参考。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句