我有一个具有@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?