我有一个具有@RequestScoped属性的List bean。

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import org.springframework.stereotype.Controller;

@Controller
@ManagedBean
@RequestScoped
public class MyBean implements Serializable {

    private List list;

    // getters and setters
}


此属性链接到数据表:

<ice:dataTable value="#{myBean.list}" ..other stuff.. />


动态填充列表是没有问题的,并且数据表显示没有问题。但是,如果我导航到另一个页面,然后返回到初始页面,则数据表仍然包含初始请求的数据。它不应该再为空吗?如果bean是请求范围的,则应在请求之后销毁它,并且我应该以空数据表作为开始。

更奇怪的是,如果我在一个浏览器(如Firefox)中打开该页面,用请求填充数据表,然后我打开另一个浏览器(如Chrome)并转到数据表页面,则该页面中填充了上一个请求中的数据从另一个浏览器!我认为bean的行为就像一个应用程序。

有任何想法吗?



更新1:该类不是静态的,也不是其变量。另外,我禁用了tomcat缓存,但仍然无法正常工作。

更新2:我认为可能找到了问题。我的后备豆用Spring的@Controller注释。我使用此注释,因为然后使用@Autowired绑定服务。可能这是在创建一个单例,为什么没有在每个请求中创建和销毁它?我认为可以肯定问题出在Spring和JSF2批注的混合中。

最佳答案

您不应该通过多个不同的bean管理框架(例如JSF,CDI和Spring)来管理单个bean。选择一个或另一个。例如,当通过Spring的@Controller管理Bean时,将忽略其他框架(如JSF的@ManagedBean和CDI的@Named)与Bean管理相关的所有注释。

我不使用Spring,也不知道为什么要使用它而不是标准的Java EE 6 API,但是症状和文档表明这种Spring bean的范围确实是应用程序范围的默认值。您需要通过Spring @Scope批注指定bean范围。您还希望删除JSF bean管理注释,因为它们不再具有任何价值,只会使开发人员/维护人员感到困惑。

@Controller
@Scope("request")
public class MyBean implements Serializable {
    // ...
}


另外,您也可以摆脱Spring @Controller批注,并坚持使用JSF @ManagedBean。您可以使用@ManagedProperty而不是@Autowired来注入另一个@ManagedBean实例,甚至可以使用Spring托管bean(如果已配置了Spring Faces EL解析器),或者可以使用Java EE标准@EJB来注入@Stateless@Stateful实例。

例如。

@ManagedBean
@RequestScoped
public class MyBean implements Serializable {

    @EJB
    private SomeService service;

    // ...
}


也可以看看:


Spring JSF integration: how to inject a Spring component/service in JSF managed bean?

07-24 19:04
查看更多