有些人会遇到自己写了个监听器,继承了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启动|退出执行事件类: import java.io.File; import java.io.FileWriter; import java.io.IOException; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import ...
ServletContextListener使用详解
通过创建ServletContextListener监听器,socket来实现tcp/ip协议客户端数据的接收功能。这是一个maven项目,直接导入eclipse即可运行,此处监听的是9092端口,将项目运行起后,可以对其端口使用情况进行查看,在...
本方案的原理是写一个实现了ServletContextListener接口的类,该类中有两个方法:public void contextInitialized,它是在应用启动时调用;另一个方法是:public void contextDestroyed,该方法是在应用结束时调用。
ServletContextListener的应用案例 项目启动:创建新的空表, 项目关闭:删除表 百度六祎,期...
public void contextInitialized(ServletContextEvent sce) { log.info("web项目的启动{} 一开始就启动",sce.getServletContext()); System.err.println("web项目的启动{}"); } @Override public ...
NULL 博文链接:https://chenhua-1984.iteye.com/blog/374683
有时候在开发Web应用的时候,需要tomcat启动后自动加载一个用户的类,执行一些初始化方法,如从数据库中加载业务字典到内存中,因此需要在tomcat启动时就自动加载一个类,或运行一个类的方法。 可以采用在WEB-INF/...
其中一种比较好的方式,是通过实现ServletContextListener接口进行坚挺,重写contextInitialized方法,实现自己需要进行的初始化操作,之后在web.xml中添加相应的listner,tomcat在启动服务时会调用相应方法。...
public void contextInitialized(ServletContextEvent event) { Map map = new TreeMap(); Book b1 = new Book(1,"core java",100); Book b2 = new Book(2,"c++",132); Book b3 = new Book(3,"php",10); ...
SpringBoot整合Listener的两种方式: ...1.创建一个类实现 ServletContextListener (具体实现哪个...3.重写 contextInitialized() 与 contextDestroyed() 方法 4.编写启动类 5.增加注解 @ServletComponentScan
ServletContextListener完成在线人数统计和显示人员列表
在SpringMVC中利用ServletContextListener初始化数据到内存
介绍了Java定时执行任务,给出了如何使用ServletContextListener实现定时运行java某个方法的例子,简单易用。
主要介绍了Java基于ServletContextListener实现UDP监听,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
启动时执行Liquibase数据库迁移 viii. 69. 批处理应用 i. 69.1. 在启动时执行Spring Batch作业 ix. 70. 执行器(Actuator) i. 70.1. 改变HTTP端口或执行器端点的地址 ii. 70.2. 自定义'白标'(whitelabel,可以...
听众 ServletContextListener,sesson,请求侦听器
JavaWeb新版教程. jsp--ServletContextListener监听器演示.avi
import java.util.*; import javax.servlet.*;... public class AmpList implements ServletContextListener,HttpSessionListener,HttpSessionAttributeListener { ... public void contextInitialized(ServletContext