I have a bunch of eager ApplicationScoped
managed beans. Some of them are injected into others by the ManagedProperty
annotation, forming a tree of dependencies. Each depending bean manipulates its parent after construction.
However, it seems like a new instance is created for each injection, thus making previous manipulations undone. To my understanding, an ApplicationScoped
bean should only be created once. Have I misunderstood or why is this happening? Is it because they are eager?
Here is an example:
package example;
import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
@ManagedBean(eager = true)
@ApplicationScoped
public class ParentBean
{
static int initCount = 0;
// ...
@PostConstruct
public void init()
{
++initCount; // Will end up being between 1 and 3. Expected always 1.
// ...
}
}
package example;
import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
@ManagedBean(eager = true)
@ApplicationScoped
public class Child1Bean
{
@ManagedProperty("#{parentBean}") ParentBean parentBean;
public ParentBean getParentBean()
{
return parentBean;
}
public void setParentBean(ParentBean parentBean)
{
this.parentBean = parentBean;
}
@PostConstruct
public void init()
{
// manipulate parentBean
}
}
package example;
import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
@ManagedBean(eager = true)
@ApplicationScoped
public class Child2Bean
{
@ManagedProperty("#{parentBean}") ParentBean parentBean;
public ParentBean getParentBean()
{
return parentBean;
}
public void setParentBean(ParentBean parentBean)
{
this.parentBean = parentBean;
}
@PostConstruct
public void init()
{
// manipulate parentBean
}
}
I have hopefully resolved this problem on Tomcat 8 + Mojarra 2.2.0. In my case I just removed listener declaration from web.xml
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
Constructor seems to be called once afterwards.
About listener entry, there is a part of BalusC answer of this question.
In any case, the explicit registration of Mojarra's ConfigureListener in web.xml is actually only necessary to workaround old buggy servers such as GlassFish v3 and Jetty who failed to find the listener in Mojarra's TLD file. When deployed to a decent server, the whole entry is unnecessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With