查看tomcat 7.0 源码:
/** * Load and initialize all servlets marked "load on startup" in the * web application deployment descriptor. * * @param children Array of wrappers for all currently defined * servlets (including those not declared load on startup) */ /** * StandardContext类,代表webapps目录下的一个web应用 * 方法会被startInternal调用(),也就是应用在启动的时候 * @param children * @return */ public boolean loadOnStartup(Container children[]) { // Collect "load on startup" servlets that need to be initialized //用TreeMap来排序 默认为natural order,也就是按ascii码 TreeMap<Integer, ArrayList<Wrapper>> map = new TreeMap<Integer, ArrayList<Wrapper>>(); for (int i = 0; i < children.length; i++) { Wrapper wrapper = (Wrapper) children[i]; //每个Wrapper对应一个Servlet,负责创建、初始化、销毁servlet,并为其提供ServletConfig int loadOnStartup = wrapper.getLoadOnStartup(); if (loadOnStartup < 0) //如果loadOnStartup的配置参数小于0,则不添加到TreeMap中 continue; Integer key = Integer.valueOf(loadOnStartup); ArrayList<Wrapper> list = map.get(key); if (list == null) { list = new ArrayList<Wrapper>(); map.put(key, list); } list.add(wrapper); } // Load the collected "load on startup" servlets //按loadOnStartup 的natural order即升序,依次对servlet进行初始化 for (ArrayList<Wrapper> list : map.values()) { for (Wrapper wrapper : list) { try { //此方法包含对servlet的实例化和init方法的调用 wrapper.load(); } catch (ServletException e) { getLogger().error(sm.getString("standardContext.loadOnStartup.loadException", getName(), wrapper.getName()), StandardWrapper.getRootCause(e)); // NOTE: load errors (including a servlet that throws // UnavailableException from the init() method) are NOT // fatal to application startup // unless failCtxIfServletStartFails="true" is specified if (getComputedFailCtxIfServletStartFails()) { return false; } } } } return true; }
代码和清晰
总结:如果web.xml中的servlet没有配置 <load-on-startup>
标签或者其值小于0,那么在容器启动时不会对其初始化;否则按照数字升序排列串行对其初始化(这也证实了 正数的值越小,启动该servlet的优先级越高
这句话)。
来自:https://blog.csdn.net/joenqc/article/details/73497804
自己动手 单独测试了一下:
一、创建最新的dynamic web project
二、在WebContent目录中(即网站根目录),创建 index.jsp 如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h3> helleo word</h3> </body> </html>
三、编辑web.xml 文件 如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>webXml</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>S1</servlet-name> <servlet-class>com.web.servlet.S1</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>S2</servlet-name> <servlet-class>com.web.servlet.S2</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet> <servlet-name>S3</servlet-name> <servlet-class>com.web.servlet.S3</servlet-class> <load-on-startup>-1</load-on-startup> </servlet> <servlet> <servlet-name>S4</servlet-name> <servlet-class>com.web.servlet.S4</servlet-class> <load-on-startup>4</load-on-startup> </servlet> <servlet> <servlet-name>S5</servlet-name> <servlet-class>com.web.servlet.S5</servlet-class> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>S1</servlet-name> <url-pattern>/s1</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>S2</servlet-name> <url-pattern>/s2</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>S3</servlet-name> <url-pattern>/s3</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>S4</servlet-name> <url-pattern>/s4</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>S5</servlet-name> <url-pattern>/s5</url-pattern> </servlet-mapping> </web-app>
四、创建 servlet 文件:
在 com.web.servlet 下面创建 5个 差不多的 servlet (eclipse 右键新建 servlet 即可) ,仅在 url ,构造函数 上进行了修改
S1 代码:
package com.web.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class S1 */ @WebServlet(name = "S001", urlPatterns = { "/001" }) public class S1 extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public S1() { super(); System.out.println("S1:init ready"); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
同理 S2代码如下:
package com.web.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class S1 */ @WebServlet(name = "S002", urlPatterns = { "/002" }) public class S2 extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public S2() { super(); System.out.println("S2:init ready"); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
其他servlet代码 类似
五、测试结果总结:
1、load on startup 大于等于 0,服务器启动时,会加载servlet ,并调用servlet的init方法。当以后 用 url 再访问 servlet时,servlet 不会再创建了,直接回把之前创建好的,直接拿过来用了。
@Override public void init() throws ServletException { // TODO Auto-generated method stub super.init(); }
如果load on startup 值小于0,那么服务器启动时不会加载,直达 调用时才会 加载。加载完成后,以后调用时,就直接拿来用了,不会再创建第二遍了。
2、servlet 3.0 加入了注解功能,我上面写的S1。。。都用了注解。url 可以用/S1访问,也可以用 /001 访问。因为 同一个 servlet 配置时取了两个名字,两个路径。服务器 启动时,会当做两个 servlet 来处理,每种 url 访问都会创建一次。