Eager ApplicationScoped managed beans constructed multiple times

别说谁变了你拦得住时间么 提交于 2019-11-29 15:03:09

问题


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:

ParentBean.java

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.

        // ...
    }
}

Child1Bean.java

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
    }
}

Child2Bean.java

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
    }
}

回答1:


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.




回答2:


I have same problems with Mojarra 2.0.x. I guess that problem is connected with multithreaded JSF initilization. Try disabling it by com.sun.faces.enableMultiThreadedStartup parameter.



来源:https://stackoverflow.com/questions/13007291/eager-applicationscoped-managed-beans-constructed-multiple-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!