CDI bean构造函数和@PostConstruct多次调用

时间:2013-05-28 15:49:45

标签: jsf primefaces cdi

经过一些实验,这在使用CDI bean时似乎是一个问题,与我最初假设的PrimeFaces无关。

如果我使用@ManagedBean将TableBeanLazy更改为Managed Bean,那么构造函数和@PostConstruct方法只会被调用一次,就像我期望的那样。

任何人都可以对此有所了解吗?

=============================================== ====

我是JSF和PrimeFaces的新手,所以任何指导都会非常感激。我搜索了其他帖子,并阅读了许多类似的帖子,但找不到解决方案。

我正在尝试在我的项目中使用PrimeFaces Showcase站点上的延迟加载数据表示例,但由于bean类的行为不像我期望的那样,我遇到了问题。

我对PrimeFaces站点的示例代码进行了一些更改: - 将TableBean类重命名为TableBeanLazy;在课堂上添加了注释;分配静态字符串数组;将初始化从构造函数移动到@PostConstruct initialise()方法;分配了 cars 成员变量。

我还在构造函数和@PostConstruct方法中添加了跟踪消息,这些消息显示在首次显示表时多次调用它们,每次单击搜索图标多次调用,并且每个字符多次调用在过滤器字段中输入。

这会导致每次执行操作时都会重新创建Car对象的随机列表,因此sort和filter将永远不会产生预期的结果 - 这是在PrimeFaces Showcase站点上直接运行示例时所做的。

虽然我最初使用@ViewScoped,但我也尝试过@RequestScoped,最后是@SessionScoped,但所有行为都是一样的。

对构造函数和@PostConstruct的多次调用是否是bean的预期行为?

如果是这样,PrimeFaces Showcase网站上提供的示例代码怎么可能有效呢?

如何解决此问题?

环境

PrimeFaces 3.5
JSF 2.1
JDK 1.7
GlassFish Server Open Source Edition 3.1.2.2 (build 5)
Mojarra 2.1.6 (SNAPSHOT 20111206)
Netbeans IDE 7.3
Windows 7 Pro x64

MyTable.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  template="./resources/templates/platform_tpl.xhtml"
  xmlns:p="http://primefaces.org/ui"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core">

  <ui:define name="body">
    <h2 style="margin-top: 0px; padding-top: 0px;">Cars List</h2>

    <h:form id="form">
      <p:dataTable var="car" value="#{tableBeanLazy.lazyModel}" paginator="true" rows="10"
        paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
        rowsPerPageTemplate="5,10,15" selectionMode="single" selection="#{tableBeanLazy.selectedCar}" id="carTable" lazy="true">

      <p:column headerText="Model" sortBy="#{car.model}" filterBy="#{car.model}">
        <h:outputText value="#{car.model}" />
      </p:column>

      <p:column headerText="Year" sortBy="#{car.year}" filterBy="#{car.year}">
        <h:outputText value="#{car.year}" />
      </p:column>

      <p:column headerText="Manufacturer" sortBy="#{car.manufacturer}" filterBy="#{car.manufacturer}">
        <h:outputText value="#{car.manufacturer}" />
      </p:column>

      <p:column headerText="Color" sortBy="#{car.color}" filterBy="#{car.color}">
        <h:outputText value="#{car.color}" />
      </p:column>
      </p:dataTable>
    </h:form> 
  </ui:define>
</ui:composition>

TableBeanLazy.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package BackEnd;

import java.util.ArrayList;
import java.util.List;  
import javax.annotation.PostConstruct;
import javax.faces.bean.SessionScoped;
import javax.inject.Named;

import org.primefaces.model.LazyDataModel;  

@Named(value = "tableBeanLazy")
@SessionScoped
public class TableBeanLazy
{
  static String[] colors = new String[10];
  static String[] manufacturers = new String[10];
  static String[] models = new String[5];

  private LazyDataModel<Car> lazyModel;  

  private Car selectedCar;  

  private List<Car> cars;  

  static
  {
    colors[0] = "Black";  
    colors[1] = "White";  
    colors[2] = "Green";  
    colors[3] = "Red";  
    colors[4] = "Blue";  
    colors[5] = "Orange";  
    colors[6] = "Silver";  
    colors[7] = "Yellow";  
    colors[8] = "Brown";  
    colors[9] = "Maroon";  

    manufacturers[0] = "Mercedes";  
    manufacturers[1] = "BMW";  
    manufacturers[2] = "Volvo";  
    manufacturers[3] = "Audi";  
    manufacturers[4] = "Renault";  
    manufacturers[5] = "Opel";  
    manufacturers[6] = "Volkswagen";  
    manufacturers[7] = "Chrysler";  
    manufacturers[8] = "Ferrari";  
    manufacturers[9] = "Ford";

    models[0] = "Sports";
    models[1] = "Saloon";
    models[2] = "SUV";
    models[3] = "Hybrid";
    models[4] = "Estate";
  }  

  public TableBeanLazy()
  {
    System.out.println("-->  In constructor for TableBeanLazy");
  }

  @PostConstruct
  public void initialise()
  {
    System.out.println("-->  In initialise for TableBeanLazy");

    cars = new ArrayList<Car>();

    populateRandomCars(cars, 5);

    lazyModel = new LazyCarDataModel(cars);  
  }

  public Car getSelectedCar()
  {
    return selectedCar;
  }  

  public void setSelectedCar(Car selectedCar)
  {
    this.selectedCar = selectedCar;
  }

  public LazyDataModel<Car> getLazyModel()
  {
    return lazyModel;
  }

  private void populateRandomCars(List<Car> list, int size)
  {
    System.out.println("-->  In populateRandomCars for TableBeanLazy");

    for(int i = 0 ; i < size ; i++)
    {
      list.add(new Car(getRandomModel(), getRandomYear(), getRandomManufacturer(), getRandomColor()));  
    }  
  }  

  private String getRandomColor()
  {
    return colors[(int)(Math.random() * 10)];
  }

  private String getRandomManufacturer()
  {
    return manufacturers[(int) (Math.random() * 10)];
  }

  private String getRandomModel()
  {
    return models[(int)(Math.random() * 5)];
  }

  private int getRandomYear()
  {
    return (int)(Math.random() * 50 + 1960);
  }
}

表格初次显示时的输出

INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy

点击搜索图标时的输出

INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
  at org.primefaces.model.LazyDataModel.setRowIndex(LazyDataModel.java:62)
  at org.primefaces.component.api.UIData.setRowModel(UIData.java:409)
  at org.primefaces.component.api.UIData.setRowIndex(UIData.java:401)
  at org.primefaces.component.api.UIData.processChildren(UIData.java:289)
  at org.primefaces.component.api.UIData.processPhase(UIData.java:261)
  at org.primefaces.component.api.UIData.processDecodes(UIData.java:227)
  at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:506)
  at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
  at org.primefaces.component.api.UIData.visitTree(UIData.java:639)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIForm.visitTree(UIForm.java:344)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
  at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
  at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
  at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:931)
  at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
  at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
  at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
  at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
  at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
  at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
  at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
  at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
  at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
  at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
  at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
  at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
  at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
  at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
  at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
  at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
  at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
  at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
  at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
  at java.lang.Thread.run(Thread.java:722)

INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
  at org.primefaces.model.LazyDataModel.setRowIndex(LazyDataModel.java:62)
  at org.primefaces.component.api.UIData.setRowModel(UIData.java:409)
  at org.primefaces.component.api.UIData.setRowIndex(UIData.java:401)
  at org.primefaces.component.api.UIData.processChildren(UIData.java:289)
  at org.primefaces.component.api.UIData.processPhase(UIData.java:261)
  at org.primefaces.component.api.UIData.processValidators(UIData.java:241)
  at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:508)
  at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
  at org.primefaces.component.api.UIData.visitTree(UIData.java:639)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIForm.visitTree(UIForm.java:344)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
  at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
  at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
  at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1170)
  at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
  at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
  at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
  at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
  at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
  at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
  at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
  at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
  at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
  at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
  at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
  at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
  at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
  at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
  at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
  at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
  at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
  at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
  at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
  at java.lang.Thread.run(Thread.java:722)

INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
  at org.primefaces.model.LazyDataModel.setRowIndex(LazyDataModel.java:62)
  at org.primefaces.component.api.UIData.setRowModel(UIData.java:409)
  at org.primefaces.component.api.UIData.setRowIndex(UIData.java:401)
  at org.primefaces.component.api.UIData.processChildren(UIData.java:289)
  at org.primefaces.component.api.UIData.processPhase(UIData.java:261)
  at org.primefaces.component.api.UIData.processUpdates(UIData.java:253)
  at org.primefaces.component.datatable.DataTable.processUpdates(DataTable.java:550)
  at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:510)
  at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
  at org.primefaces.component.api.UIData.visitTree(UIData.java:639)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIForm.visitTree(UIForm.java:344)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
  at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
  at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
  at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1229)
  at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
  at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
  at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
  at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
  at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
  at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
  at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
  at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
  at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
  at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
  at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
  at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
  at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
  at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
  at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
  at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
  at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
  at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
  at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
  at java.lang.Thread.run(Thread.java:722)

INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy

1 个答案:

答案 0 :(得分:9)

以下是您对CDI和JSF的第一条建议 - 永远不要将CDI与JSF注释混合。

您的问题是您使用@javax.inject.Named CDI注释javax.faces.bean.SessionScoped - JSF注释。

在CDI中你会这样做:

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named(value = "tableBeanLazy")
@SessionScoped
public class TableBeanLazy {...}

请注意,上面的内容与JSF完全一致。

以纯JSF方式执行:

import javax.faces.bean.SessionScoped;
import javax.faces.bean.ManagedBean;

@ManagedBean(value = "tableBeanLazy")
@SessionScoped
public class TableBeanLazy {...}

我建议一直坚持使用CDI。但是,CDI目前没有提供开箱即用的JSF @javax.faces.bean.ViewScoped的替代方案。要在CDI中获取它,请查看Apache Deltaspike。