5

@ApplicationScoped でクラスに注釈を付けました。@Inject を使用して、このクラスのインスタンスをいくつかの @RequestScopded JAX-RS サービスに注入します。

@ApplicationScoped
public class MySingleton {
  MySingleton() {
    System.out(this + " created.");
  }
}

@RequestScoped
public class MyRS {
  @Inject MySingleton mySingleton;
  public void someMethod() {
    // do something with mySingleton
  }
}

基本的にこれでうまくいきます。ただし、少なくともこれを WebSphere 8.5 で実行すると、MySingleton のコンストラクターが 2 回呼び出され、次のような出力が得られます。

my.package.MySingleton_$$_javassist_26@cddebf9b created.
my.package.MySingleton@e51e26d1 created.

コンストラクターで高価な初期化を行うことを計画しましたが、これは明らかに 2 回実行されます。

コンストラクター呼び出しの 1 つは、実際の「ワーカー」インスタンスに対して何らかのプロキシを生成するためのものだと思います。しかし、初期化コードが 2 回実行されないようにするにはどうすればよいでしょうか? MySingleton のすべてのメソッドで遅延初期化を行う「解決策」はあまり魅力的ではありません。

4

2 に答える 2

10

管理対象 Bean のコンストラクターは、プロキシーを作成するためにコンテナーから呼び出すこともできます。したがって、「実際の」初期化のために、Java EE は注釈 @PostConstruct を提供します。@ApplicationScoped Bean では、@PostConstruct でアノテーションが付けられたメソッドがコンテナーによって 1 回だけ呼び出されます。

@ApplicationScoped
public class MySingleton {
  MySingleton() {
    System.out(this + " created.");
  }
  @PostConstruct
  init() {
    System.out(this + " initd.");
  }
}

出力:

my.package.MySingleton_$$_javassist_26@cddebf9b created.
my.package.MySingleton@e51e26d1 created.
my.package.MySingleton@e51e26d1 initd.

関連する質問: @PostConstruct を使用する理由

于 2013-08-26T09:40:05.027 に答える
0

これは、シングルトン用に作成された javassist プロキシ オブジェクトです。シングルトン コンストラクターは、実際のオブジェクトの作成時に呼び出す必要があります。

于 2013-08-22T17:51:54.457 に答える