[英]Overridden @PostConstruct called twice on CDI view-scoped bean (Weld, Seam 3)
我们在基类层次结构上遇到重复的@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上)。
是的,它已被修复。 不幸的是,它仅在Weld 2.0版本系列中得到修复。 有时这些错误会被移植回来,但不幸的是我怀疑这个错误最终会在维护版本中得到解决。
这是一个解决方法的答案。
提到Bug时,会考虑@PostConstruct注释,并执行它们的逻辑代码。
要解决此问题,可以执行以下操作:
因此,您只需在子类上执行标记为@PostConstruct的代码:
@Specializes
@ViewAccessScoped
public class BaseBean extends SubBean {
@PostConstruct
public void postConstructExtension() {
LOGGER.info("POST CALLED ON SPECIALIZED CLASS" + this.getClass().getSimpleName());
}
@Override
public void postConstruct() {
LOGGER.info("OVERRIDDEN POST CALLED ON SPECIALIZED CLASS" + this.getClass().getSimpleName());
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.