我们在@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
被调用了两次。这是输出:
INFO: AbstractManager @PostConstruct on PseudoEntityManager!
INFO: AbstractManager @PostConstruct on PseudoEntityManager!
INFO: New list of pseudo DB entities!
当在具体子类中注释覆盖init()
方法以使超类中只有一个方法时,将生成以下输出:@PostConstruct
INFO: AbstractManager @PostConstruct on PseudoEntityManager!
INFO: New list of pseudo DB entities!
问:
现在根据 CDI 规范的正确行为是什么?(参考任何人?)
笔记:
我在研究时还发现了这个邮件列表对话:
在谈话中,一些大师倾向于说“应该只调用子类上的@PostConstruct 方法”。如果您仔细阅读,有一个 Weld 错误的链接,据说该错误自 Weld 1.1.5 起已解决:
https://issues.jboss.org/browse/WELD-1225
这个问题真的解决了吗?根据我得到的输出,它不是。
环境:焊接 1.1.8 和 Seam 3 以使 CDI @ViewScoped 正常工作(在 GlassFish 3.1.2 上)。