5

我有一堆急切 ApplicationScoped的托管豆子。其中一些通过ManagedProperty注解注入到另一些中,形成依赖树。每个依赖 bean 在构造后都会操作其父级。

但是,似乎每次注入都会创建一个新实例,从而撤消先前的操作。据我了解,一个ApplicationScopedbean 应该只创建一次。我是否误解或为什么会发生这种情况?是因为他们渴望吗?

这是一个例子:

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

2 回答 2

1

我希望在 Tomcat 8 + Mojarra 2.2.0 上解决了这个问题。就我而言,我刚刚从 web.xml 中删除了侦听器声明

<listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>

构造函数似乎在之后被调用一次。

关于监听器条目,有一部分 BalusC 回答了这个问题。

无论如何,在 web.xml 中显式注册 Mojarra 的 ConfigureListener 实际上只需要解决旧的错误服务器,例如 GlassFish v3 和 Jetty,这些服务器未能在 Mojarra 的 TLD 文件中找到侦听器。当部署到一个像样的服务器时,整个条目是不必要的。

于 2016-02-12T11:23:22.600 回答
0

我对 Mojarra 2.0.x 也有同样的问题。我猜这个问题与多线程 JSF 初始化有关。尝试通过 com.sun.faces.enableMultiThreadedStartup 参数禁用它。

于 2012-10-22T10:38:18.087 回答