我正在尝试使用x86_64 OpenJDK 1.6在Linux上的Tomcat 6.24中实现Singleton。
我的应用程序只是一堆JSP和一些静态内容,而JSP则调用我的Java代码。目前web.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>
在我尝试加载我的Singleton之前,它被实例化了两次,因为类被两个不同的类加载器加载(我不知道为什么)并且每个加载器都会创建一个单例的实例,这是不可接受的为我的申请。我终于弄明白,如果我将我的代码导出为jar并将其放在$ CATALINA_HOME / lib中,那么只有一个实例,但这不是一个优雅的解决方案。
我一直在谷歌搜索几个小时,但我还没有拿出任何东西。我想知道是否还有其他解决方案。目前我没有预先编译我的JSP,这可能是问题的一部分吗?我可以编写一个servlet来确保创建单例吗?如果是这样,我该怎么做?
答案 0 :(得分:2)
好的,我终于找到了问题。
我通过添加到server.xml并将路径设置为“”使我的应用程序成为服务器的默认应用程序。但是,当我通过网址http://localhost/somepage.jsp访问某些内容时,以及其他内容的网址http://localhost/appname/anotherpage.jsp。
我将所有网址更改为使用http://localhost/而不是http://localhost/appname后问题得到解决。
答案 1 :(得分:1)
为确保正确初始化Singleton,您应该检查您是否使用默认的父级优先级类加载器,请参阅http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html。
然后在方法中定义ServletContextListener并初始化您的Singleton:
contextInitialized(ServletContextEvent sce)
保证在任何servlet或过滤器之前调用。
所有ServletContextListeners都是 通知上下文初始化 在任何过滤器或servlet之前 Web应用程序已初始化。
在web.xml中定义ServletContextListener
答案 2 :(得分:0)
什么时候首先创建单身?您可以通过包含:
强制在加载index.jsp
时创建它
<%! MySingleton instance = MySingleton.getInstance(); %>
线。
如果您预先编译jsp并将tomcat配置为永远不会自动重新加载类或jsp,则单例应保持单一: - )
答案 3 :(得分:0)
我将所有网址更改为使用http://localhost/而不是http://localhost/appname后问题得到解决。
这意味着您已经部署了2个Web应用程序并希望它们使用相同的类加载器。这是不真实的。如果您需要所有Web应用程序使用的共享库,则应将其放在“Tomcat Shared”(可由shared.loader
文件中的catalina.properties
配置)表示的路径中。您只需要确保在webapp自己的库或Tomcat / lib中不拥有此库。