共计 1811 个字符,预计需要花费 5 分钟才能阅读完成。
有些人会遇到自己写了个监听器,继承了 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 下,所以在访问时,就只能是:这样来访问了。
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2017-10/147812.htm
![post-qrcode](https://www.xgss.net/wp-content/uploads/2023/07/二维码-微信公众号256x256.jpg)