这里有2个工作示例,它们具有相同的目的:检索对应用程序全局的FAQ结果。我们根据输入的值获取结果并更新数据表。
第一个使用RequestScoped和bean绑定。第二个使用ApplicationScoped bean和视图绑定。
示例1:
xhtml<h:inputText id="faqSearch" value="#{faqBean.filter}"/>
<h:commandButton value="submit" ajax="true" update="faqResults"/>
<h:dataTable
id="faqResults"
value="#{faqBean.retrieveResults()}"
var="result">
<h:column>${result}</h:column>
</h:dataTable>
憨豆@RequestScoped
@ManagedBean
public class FaqBean {
String filter;
public String getFilter(){
return filter;
}
public void setFilter(String filter){
this.filter = filter;
}
public List<String> retrieveResults(){
//compute result from a backend service based on filter
return doSomething(filter);
}
示例2:
xhtml<h:inputText id="faqSearch" binding="#{filter}"/>
<h:commandButton value="submit" ajax="true" update="faqResults"/>
<h:dataTable
id="faqResults"
value="#{faqBean.retrieveResults(filter.value)}"
var="result">
<h:column>${result}</h:column>
</h:dataTable>
憨豆@ApplicationScoped
@ManagedBean
public class FaqBean {
public List<String> retriveResults(String filter){
//Compute result from a backend service based on filter
return doSomething(filter);
}
所以1似乎是jsf的好方法。
但对我来说,2似乎是一个更好的解决方案,因为它不会在每次执行时创建/销毁bean, bean对应用程序来说是静态的。
但是用这种思维方式,我们可以摆脱所有requestscoped bean,所以感觉不对。也许这个解决方案比第一个更糟糕,我不知道这一切是如何管理的。
那么有什么更好的方法呢?
这将是一个意见问题,而不是分析服务器为每个请求创建一个新的bean实例所花费的成本。如果每个请求只检索一个值,那么任何这些实现都是有效的,也许你应该使用后者,但,因为它看起来不像一个真正的用例,你不执行任何业务逻辑,总是检索单个结果,但你可以有不同的过滤器每个请求,那么第一个更好,因为你的getter必须尽可能干净。这意味着,在JSF托管bean中,getter 不应该具有任何业务逻辑,因为应用程序可以多次调用它们。因此,当您添加一些业务逻辑来处理过滤器时,您将意识到每个请求都可以返回不同的结果,这将导致使用使用@RequestScoped
bean的前一种实现。
由于您的真正问题是关于检索所有应用程序的全局FAQ信息,您应该在应用程序的全局资源(如缓存空间或另一个@ApplicationScoped
bean)中加载FAQ数据,然后针对该全局资源执行每个请求,以避免触及数据库。
更多信息:
- 为什么JSF多次调用getter