`
韩悠悠
  • 浏览: 842563 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Tomcat 启动两次的问题(ServletContextListener的contextInitialized被执行两次的问

    博客分类:
  • web
 
阅读更多

 

有些人会遇到自己写了个监听器,继承了ServletContextListener,在Tomcat等服务器启动的时候contextInitialized方法被执行了两次,百思不得其解。

其实,实际上不是简单的contextInitialized方法被调用两次,是Tomcat被启动了两次(或者说放到Tomcat的webapps中的Web应用被启动了两次)

为什么这么说呢?(上面红色加粗的观点),因为像下面配置的一个Servlet,也是会被new两次的(可以在其init方法内打印语句,可以看到打印了两条!)。这就说明并不仅仅是contextInitialized被执行了两次,说明的是在web.xml中配置的启动Tomcat就new出Servlet的对象也被new了两次。进而可以把结论更加推广-------------------其实是整个Web应用被启动了两次,或者在网上有种更加通俗但我认为不准确的说法:Tomcat被启动了两次。

<servlet>
  <servlet-name>ProxyBean</servlet-name>
  <servlet-class>work.servlet.ServletProxy</servlet-class>
  <init-param>
   <param-name>targetBean</param-name>
   <param-value>toHtml</param-value>
  </init-param>
  <load-on-startup>40</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>ProxyBean</servlet-name>
  <url-pattern>/ToHtml.do</url-pattern>
 </servlet-mapping>

 

下面转载别人的文章,解决问题了。我是采用了把Web应用不放在Tomcat的webapps上,而放到与webapps之外与webapps文件夹同级的文件夹WEBROOT下

这个做法顺带还解决了以前一个矛盾的、纠结了很久的问题:为什么我的log4j记录日志会出现昨天的日志被今天的日志覆盖,用于只有一份最新的,log4j的配置文件是绝对绝对正确的。

前提:

    1、存在某个应用:hello

    2、该应用存放路径:D:\apache-tomcat-5.5.17\webapps\hello

    3、Tomcat的server.xml部分配置信息如下:

...

<Context path="" reloadable="true" docBase="hello"/>

...

    (这么做的目的就是为了将hello应用设为根,访问IP时就直接访问该应用)

    4、hello下有一个 servlet(目的是为了系统在启动时执行某些初始化的操作),该servlet里存在init()方法,目前该方法里只打印“hello word”字符串;

     5、hello 应用的 web.xml 部分配置信息如下:

<servlet>

    <servlet-name>HelloServlet</servlet-name>

    <servlet-class>HelloServlet</servlet-class>

    <load-on-startup>1</load-on-startup>

</servlet>

 

问题:

    在启动 tomcat5 时,控制台窗口会打印出两行“hello word”字符串?

 

问题原因:

    因为hello应用本来就放在Tomat的默认webapp目录下(tomcat在启动时肯定会加载1次),然后又在server.xml中做了配置,为了达到访问根就可以访问hello应用(这样tomcat就又加载1次);结果,Tomcat就会加载两次。

 

解决办法:

    办法1、不要将 hello 应用放在Tomat的默认webapp目录下,把它移出去,然后在server.xml中修改docBase的值为hello应用在新位置的绝对路径就可以了;

    办法2、删除掉server.xml中 Context 的手动配置,这样就不会加载两次,因为hello应用在webapp下,所以在访问时,就只能是: 这样来访问了。

分享到:
评论

相关推荐

    tomcat启动|退出执行事件

    tomcat启动|退出执行事件类: import java.io.File; import java.io.FileWriter; import java.io.IOException; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import ...

    Tomcat启动时,自动访问本地servlet

    这个监听器需要继承`javax.servlet.ServletContextListener`接口并实现其`contextInitialized`方法。在这个方法中,我们可以调用Servlet的URL,使其在Tomcat启动时被访问: ```java import javax.servlet.*; import...

    timer随tomcat启动案例

    当Tomcat服务器启动时,会触发`contextInitialized`方法,我们可以在该方法中初始化我们的`Timer`,设置好定时任务,这样就可以确保任务在服务器启动时一同运行。 以下是实现步骤: 1. 创建一个Java类,实现`...

    ServletContextListener使用详解

    在 ServletContextListener 接口中定义了处理 ServletContextEvent 事件的两个方法:contextInitialized() 和 contextDestroyed()。 contextInitialized() 方法是在 Servlet 容器启动 Web 应用时被调用的。在调用完...

    ServletContextListener,Timer,TimerTask学习笔记

    当Web应用启动时,服务器会自动调用实现了`ServletContextListener`接口类的`contextInitialized`方法,而在Web应用停止时,会调用`contextDestroyed`方法。这为开发者提供了一个全局的、统一的入口点来执行一些初始...

    ServletContextListener的应用

    在Java Web开发中,`ServletContextListener`是一个非常重要的接口,它是Servlet API的一部分,定义了两个方法:`contextInitialized`和`contextDestroyed`。这个接口的主要作用是监听Servlet上下文(`...

    如何让tomcat服务增加java启动命令

    ServletContextListener接口有两个重要的方法:contextInitialized和contextDestroyed,这两个方法分别在Tomcat启动和关闭时被调用。我们可以在contextInitialized方法中执行游戏的主函数,以实现自启动。 三、计时...

    Tomcat中简易定时器的实现

    `YourTimerInitializer`是一个自定义的监听器类,它需要实现`ServletContextListener`接口,并在`contextInitialized`方法中创建并启动定时器: ```java import javax.servlet.ServletContextEvent; import javax....

    SpringMVC中ervletContextListener的使用

    `ServletContextListener`是一个接口,它包含两个方法:`contextInitialized`和`contextDestroyed`。当Web应用程序启动时,服务器会调用`contextInitialized`方法,而在应用程序关闭时调用`contextDestroyed`。...

    如何在Web应用中去启动后台的任务

    通过以上步骤,Web应用在启动时会自动运行`ServiceLoader.contextInitialized`,从而启动后台任务,而在应用关闭时,`ServiceLoader.contextDestroyed`会被调用,停止后台任务,确保了任务生命周期与Web应用同步。...

    ServletContextListener完成在线人数统计和显示人员列表

    要创建一个`ServletContextListener`,你需要实现`javax.servlet.ServletContextListener`接口,并重写两个方法:`contextInitialized(ServletContextEvent sce)`和`contextDestroyed(ServletContextEvent sce)`。...

    jsp定时执行的三种方法

    当Web应用启动时,监听器会自动触发`contextInitialized`方法,在这里可以创建并启动定时任务;而当应用关闭时,`contextDestroyed`方法会被调用,用于停止定时任务。在`web.xml`配置文件中添加监听器即可: ```xml...

    java 监听使用

    - `contextInitialized()`:该方法会在Web应用被加载到容器中时调用。 - `contextDestroyed()`:该方法会在Web应用从容器卸载时调用。 3. **配置监听器**:接下来,在`web.xml`文件中注册这个监听器。 ##### 2.2 ...

    tomcat监听器

    例如,实现`ServletContextListener`需要覆盖`contextInitialized`和`contextDestroyed`方法。 5. **监听器与Servlet过滤器的区别** 监听器和Servlet过滤器都是处理Web应用程序生命周期的组件,但它们的焦点不同。...

    java如何实现项目启动时执行指定方法

    这样,当项目启动时, InitListener 类的 contextInitialized 方法将被执行,从而执行指定的方法。 总结来说,使用 ServletContextListener 可以轻松地实现 Java 项目启动时执行指定方法。通过实现这个接口,我们...

    利用servlet监听器,系统启动时创建自定义容器简单例子

    要创建一个监听器,你需要编写一个类,实现`ServletContextListener`接口,并重写它的两个方法:`contextInitialized(ServletContextEvent sce)`和`contextDestroyed(ServletContextEvent sce)`。前者在Web应用启动...

    tomcat embedded + sqlite

    这可能包括在`ServletContextListener`中创建数据库连接池,或者在应用程序启动时执行初始化脚本。 **源码分析** 标签中的“源码”意味着可能有关于实际代码实现的详细信息。在博文链接中,你可能会找到如何配置和...

    java定时任务,每天定时执行任务

    在 NFDFlightDataTaskListener 类中,我们实现了 contextInitialized 方法,在这个方法中,我们创建了 TimerManager 对象,并启动了定时任务的执行。 知识点 6:web.xml 配置 在 web.xml 文件中,我们需要配置 ...

    Tomcat+Redis集群所需jar

    public void contextInitialized(ServletContextEvent sce) { JedisPoolConfig poolConfig = new JedisPoolConfig(); // 设置连接池相关配置 Set&lt;HostAndPort&gt; nodes = new HashSet(); // 添加Redis集群节点,...

    JAVA自动执行任务[文].pdf

    这个接口有两个主要方法:`contextInitialized(ServletContextEvent event)`和`contextDestroyed(ServletContextEvent event)`。前者在Web应用启动时被调用,后者在Web应用关闭时被调用。我们可以利用这两个方法来...

Global site tag (gtag.js) - Google Analytics