Java Apache Tomcat在启动时以相同负载执行servlet

Java Apache Tomcat在启动时以相同负载执行servlet,java,spring,tomcat,servlets,Java,Spring,Tomcat,Servlets,我最近一直在几个JavaServlet技术方面进行实验。 最近,我遇到了web.xml的load-on-startup标记,它属于Servlet规范。我在ApacheTomcat中试验了启动时加载是如何工作的,并通过日志意识到,每个servlet执行servlet init()方法的顺序很可能基于servlet名称的字母顺序,而不是web.xml中定义servlet的顺序 web.xml文件如下所示: <?xml version="1.0" encoding="UTF-8"?> &l

我最近一直在几个JavaServlet技术方面进行实验。 最近,我遇到了web.xml的load-on-startup标记,它属于Servlet规范。我在ApacheTomcat中试验了启动时加载是如何工作的,并通过日志意识到,每个servlet执行servlet init()方法的顺序很可能基于servlet名称的字母顺序,而不是web.xml中定义servlet的顺序

web.xml文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <display-name>Hello-World-Servlet</display-name>

    <servlet>
        <servlet-name>hello-world</servlet-name>
        <servlet-class>org.wso2.carbon.HelloWorld</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>all-is-well</servlet-name>
        <servlet-class>org.wso2.carbon.HelloWorld</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>bonjour-monde</servlet-name>
        <servlet-class>org.wso2.carbon.HelloWorld</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>hello-world</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>all-is-well</servlet-name>
        <url-pattern>/well</url-pattern>
        <url-pattern>/alright</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>bonjour-monde</servlet-name>
        <url-pattern>/bonjour</url-pattern>
    </servlet-mapping>

</web-app>
public class HelloWorld extends HttpServlet {
    private static final Logger logger = Logger.getLogger(HelloWorld.class.getName());

    @Override
    public void init() throws ServletException {
        logger.log(Level.INFO, "The servlet " + getServletName() + " is starting...");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println(getServletName());
        if (getServletName().equals("hello-world")) {
            response.getWriter().println("Hello World!!!");
        } else if (getServletName().equals("bonjour-monde")) {
            response.getWriter().println("Bonjour monde!!!");
        } else if (getServletName().equals("all-is-well")) {
            response.getWriter().println("All izz well!!!");
        }
    }

    @Override
    public void destroy() {
        logger.log(Level.INFO, "The servlet " + getServletName() + " is getting destroyed...");
    }
}
15-Apr-2016 14:41:12.678 INFO [localhost-startStop-1] org.wso2.carbon.HelloWorld.init The servlet all-is-well is starting...
15-Apr-2016 14:41:12.680 INFO [localhost-startStop-1] org.wso2.carbon.HelloWorld.init The servlet bonjour-monde is starting...
15-Apr-2016 14:41:12.680 INFO [localhost-startStop-1] org.wso2.carbon.HelloWorld.init The servlet hello-world is starting...
当我检查Tomcat日志时,它如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <display-name>Hello-World-Servlet</display-name>

    <servlet>
        <servlet-name>hello-world</servlet-name>
        <servlet-class>org.wso2.carbon.HelloWorld</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>all-is-well</servlet-name>
        <servlet-class>org.wso2.carbon.HelloWorld</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>bonjour-monde</servlet-name>
        <servlet-class>org.wso2.carbon.HelloWorld</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>hello-world</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>all-is-well</servlet-name>
        <url-pattern>/well</url-pattern>
        <url-pattern>/alright</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>bonjour-monde</servlet-name>
        <url-pattern>/bonjour</url-pattern>
    </servlet-mapping>

</web-app>
public class HelloWorld extends HttpServlet {
    private static final Logger logger = Logger.getLogger(HelloWorld.class.getName());

    @Override
    public void init() throws ServletException {
        logger.log(Level.INFO, "The servlet " + getServletName() + " is starting...");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println(getServletName());
        if (getServletName().equals("hello-world")) {
            response.getWriter().println("Hello World!!!");
        } else if (getServletName().equals("bonjour-monde")) {
            response.getWriter().println("Bonjour monde!!!");
        } else if (getServletName().equals("all-is-well")) {
            response.getWriter().println("All izz well!!!");
        }
    }

    @Override
    public void destroy() {
        logger.log(Level.INFO, "The servlet " + getServletName() + " is getting destroyed...");
    }
}
15-Apr-2016 14:41:12.678 INFO [localhost-startStop-1] org.wso2.carbon.HelloWorld.init The servlet all-is-well is starting...
15-Apr-2016 14:41:12.680 INFO [localhost-startStop-1] org.wso2.carbon.HelloWorld.init The servlet bonjour-monde is starting...
15-Apr-2016 14:41:12.680 INFO [localhost-startStop-1] org.wso2.carbon.HelloWorld.init The servlet hello-world is starting...
我遇到了一些与这种行为相矛盾的资源,并提到如果启动时的负载对于几个servlet是相等的,那么它们在描述符中出现的顺序决定了顺序。 但是当提到以下内容时,规范似乎有一个不同的想法,即它取决于容器实现。这与我的经历相符


为这种情况定义的最准确的机制是什么?

好吧,您有一个说明,说明它依赖于容器,并且您已经观察到它依赖于容器的行为


因此,不要编写依赖于任何特定实现的代码。

好吧,您有说明它依赖于容器的规范,并且您已经观察到它依赖于容器的行为

因此,不要编写依赖于任何特定实现的代码。

阅读:

启动时的元素加载指示此servlet应 在启动时加载(实例化并调用其init() Web应用程序。此元素的元素内容必须是 指示servlet加载顺序的整数。如果 值为负整数,或者元素不存在,则 容器可以随时随意加载servlet。如果 值为正整数或0,容器必须加载并 在部署应用程序时初始化servlet。容器 必须保证加载标有较低整数的servlet 在用更高整数标记的servlet之前容器可以选择 具有相同启动时加载值的servlet的加载顺序

[Emphasis mine]

内容如下:

启动时的元素加载指示此servlet应 在启动时加载(实例化并调用其init() Web应用程序。此元素的元素内容必须是 指示servlet加载顺序的整数。如果 值为负整数,或者元素不存在,则 容器可以随时随意加载servlet。如果 值为正整数或0,容器必须加载并 在部署应用程序时初始化servlet。容器 必须保证加载标有较低整数的servlet 在用更高整数标记的servlet之前容器可以选择 具有相同启动时加载值的servlet的加载顺序


[Emphasis mine]

Servlet未按字母顺序加载相同的启动加载值。它取决于容器,请参阅随附的屏幕截图,以获取与Tomcat 8相同的代码。

Servlet没有按照相同的启动加载值的字母顺序加载。这取决于容器,请参阅随附的屏幕截图,以获取与Tomcat 8相同的代码