由于类加载器,java在Tomcat web应用程序中实现单例模式时遇到问题
我试图在Linux上用x86_64 OpenJDK 1.6在Tomcat 6.24中实现一个单例
我的应用程序只是一堆JSP和一些静态内容,JSP调用我的Java代码。目前在网上。xml就像这样:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<description>
App Name
</description>
<display-name>App Name</display-name>
<!-- The Usual Welcome File List -->
<welcome-file-list>
<welcome-file>pages/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
以前,当我尝试加载我的单例时,它被实例化了两次,因为类被两个不同的类加载器加载(我不知道为什么),每个加载器都会创建一个单例实例,这对于我的应用程序来说是不可接受的。我最终发现,如果我将代码导出为jar并将其放入$CATALINA_HOME/lib中,那么只有一个实例,但这不是一个优雅的解决方案
我在谷歌上搜索了几个小时,但还没有找到任何东西。我想知道是否还有其他解决办法。目前我没有预编译JSP,这可能是问题的一部分吗?我可以编写一个servlet来确保创建单例吗?如果是,我该怎么做
# 1 楼答案
第一次创建单例是什么时候?您可以通过包含以下命令来强制在加载
index.jsp
时创建它:线路
如果预编译jsp并将tomcat配置为从不自动重新加载类或jsp,则singleton应保持为single:-)
# 2 楼答案
这意味着您已经部署了2个Web应用程序,并期望它们使用相同的类加载器。这是不真实的。如果您想要一个所有Web应用程序都使用的共享库,那么应该将它放在由“Tomcat shared”表示的路径中(可通过
catalina.properties
文件中的shared.loader
进行配置)。您只需确保在webapp自己的库或Tomcat/lib中没有此库# 3 楼答案
好的,我终于解决了问题
我通过向服务器添加一个应用程序,使我的应用程序成为服务器的默认应用程序。xml并将路径设置为“”。然而,当我通过URL http://localhost/somepage.jsp访问它时,有些东西也是通过URL http://localhost/appname/anotherpage.jsp访问其他东西
一旦我将所有URL更改为使用http://localhost/而不是http://localhost/appname,问题就解决了
# 4 楼答案
为了确保单例的正确初始化,您应该检查您使用的是默认的父类第一类加载器,请参见http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html
然后定义一个ServletContextListener并在方法中初始化您的单例:
它保证在任何servlet或过滤器之前被调用
在web中定义ServletContextListener。xml