我的情况是我在运行嵌入式服务器的代码和我的Web应用程序之间共享单例。我有类和部署工具的战争。当我打印printf实例时,我看到:
abc.Abc@173a10f
abc.Abc@105738
所以这不是单身人士。这是如何工作的?
我的服务器Jetty启动代码:
public static void main(String[] args) throws Exception
{
System.out.println(MySingleton.getInstance());
// start Jetty here and deploy war with WebAppContext()
}
我的ServletContextListener
旁边代码:
public class AppServletContextListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println(MySingleton.getInstance());
}
}
我的单身人士:
public class MySingleton {
private static MySingleton INSTANCE = new MySingleton();
private MySingleton () {}
public static MySingleton getInstance() {
return INSTANCE;
}
}
我在构造函数中强制异常。看起来我有两种不同。
java.lang.Exception
at api.MySingleton.<init>(MySingleton.java:33)
at api.MySingleton.<clinit>(MySingleton.java:22)
at my.project.StartJetty.main(StartJetty.java:41)
java.lang.Exception
at api.MySingleton.<init>(MySingleton.java:33)
at api.MySingleton.<clinit>(MySingleton.java:22)
at api.AppServletContextListener.contextInitialized(AppServletContextListener.java:25)
at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:640)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:229)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1208)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:586)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:449)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:58)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:58)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:89)
at org.eclipse.jetty.server.Server.doStart(Server.java:258)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:58)
at my.project.StartJetty.main(StartJetty.java:66)
答案 0 :(得分:5)
看一些Jetty documentation。您可以使用类加载配置。
如果设置为true,那么Jetty使用普通的JavaSE类加载优先级, 并优先使用父/系统类加载器。这避免了 webapp中的一个类的多个版本的问题,但是 父/系统加载程序提供的版本必须是正确的版本 对于您以这种方式配置的所有Web应用程序。
这正是您所描述的情况。一个MySingleton
实例由主Java程序加载,另一个由Jetty的类加载器加载。
答案 1 :(得分:2)
在构造函数中打印堆栈跟踪应该为您提供所需的信息,以找出实例化的位置和顺序。单身模式是一种危险的事情,通常以不同的方式做得更好。
答案 2 :(得分:2)
您的ServletContextListener和主类由不同的类加载器加载。每当加载一个类时,它的静态块都将被执行。所以你会得到两个实例...
如果你想确保同一个类加载器加载你的单例, 你必须自己指定类加载器。
查看此链接了解更多详情 http://www.javaworld.com/article/2073352/core-java/simply-singleton.html?page=2