4

組み込みサーバーを実行するコードと Web アプリケーションの間でシングルトンを共有する状況があります。クラスと展開ツールとの戦いがあります。インスタンスを印刷すると、次のように表示されます。

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;
    }
}

コンストラクター内で例外を強制しました。私は2つの異なるものを手に入れるようです。

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)
4

3 に答える 3

5

Jetty のドキュメントを参照してください。クラスローディング構成をいじることができます。

true に設定すると、Jetty は通常の JavaSE クラスローディング優先度を使用し、親/システム クラスローダーに優先度を与えます。これにより、Web アプリケーション内のクラスの複数のバージョンの問題が回避されますが、親/システム ローダーが提供するバージョンは、この方法で構成するすべての Web アプリケーションに対して適切なバージョンである必要があります。

これはまさにあなたが説明している状況です。1 つのMySingletonインスタンスはメインの Java プログラムによってロードされ、別のインスタンスは Jetty のクラス ローダーによってロードされています。

于 2013-09-11T20:17:11.933 に答える
2

ServletContextListener とメイン クラスは、異なるクラス ローダーによってロードされます。クラスがロードされるたびに、その静的ブロックが実行されます。したがって、2つのインスタンスが得られます...

同じクラスローダがシングルトンをロードすることを確認したい場合は、クラスローダを自分で指定する必要があります。

詳細については、このリンクを確認してください http://www.javaworld.com/article/2073352/core-java/simply-singleton.html?page=2

于 2013-09-11T20:13:59.427 に答える