@PostConstruct
基本クラス階層での重複呼び出しに問題があります。
最初の基本クラスは次のとおりです。
public abstract class AbstractManager<T> implements Serializable
{
private List<T> entities;
@PostConstruct // when annotated with @PostConstruct this method is called even if overridden in sub class
public void init()
{
System.out.println( AbstractManager.class.getSimpleName() + " @PostConstruct on " + this.getClass().getSimpleName() + "!" );
}
protected abstract List<T> getDbEntities();
public List<T> getEntities()
{
if ( this.entities == null )
{
this.entities = this.getDbEntities();
}
return this.entities;
}
public void setEntities( List<T> entities )
{
this.entities = entities;
}
public void clearEntities()
{
this.entities = null;
}
}
具体的なサブクラスは次のとおりです (init() が super.init() を呼び出すためにオーバーライドされていることに注意してください)。
@Named
@ViewScoped
public class PseudoEntityManager extends AbstractManager<PseudoEntity>
{
private static final long serialVersionUID = 1L;
@Override
@PostConstruct
public void init()
{
super.init();
}
...
}
一部の (表示されていない) ページがレンダリングされると、pseudoEntityManager
Bean がインスタンス化されますが、 @PostConstruct
2 回呼び出されます。これは出力です:
INFO: AbstractManager @PostConstruct on PseudoEntityManager!
INFO: AbstractManager @PostConstruct on PseudoEntityManager!
INFO: New list of pseudo DB entities!
具体的なサブクラスのオーバーライドinit()
メソッドをコメント化して、スーパー クラスのメソッドが1 つだけになるようにすると、次の出力が生成されます。@PostConstruct
INFO: AbstractManager @PostConstruct on PseudoEntityManager!
INFO: New list of pseudo DB entities!
Q :
現在の CDI 仕様による正しい動作は何ですか? (誰かを参照しますか?)
ノート:
調査中に、このメーリングリストの会話も見つけました。
会話の中で、「サブクラスの @PostConstruct メソッドのみを呼び出す必要がある」と言う専門家もいます。よく読むと、Weld 1.1.5 以降に解決されたと言われている Weld バグへのリンクがあります。
https://issues.jboss.org/browse/WELD-1225
これは本当に修正されましたか?私が得た出力によると、そうではありません。
環境: (GlassFish 3.1.2 で) CDI @ViewScoped が正しく動作するように Seam 3 と共に 1.1.8 を連結します。