Jsf 减少对贪婪方法的多次调用

Jsf 减少对贪婪方法的多次调用,jsf,jsf-2,scope,Jsf,Jsf 2,Scope,我有以下JSF 2.0 bean: @ApplicationScoped class GreedyBean { Result doGreedyStuff(String userId) { ... // Takes lots of machine resources and time. } } @SessionScoped class MyPageBean { String userId; GreedyBean greedyBean; String getFirstG

我有以下JSF 2.0 bean:

@ApplicationScoped
class GreedyBean {
  Result doGreedyStuff(String userId) {
    ... // Takes lots of machine resources and time.
  }
}

@SessionScoped
class MyPageBean {
  String userId;
  GreedyBean greedyBean;
  String getFirstGreedyStuffStat() {
    Result result = greedyBean.doGreedyStuff(userId);
    return result.getString();
  }
  int getSecondGreedyStuffStat() {
    Result result = greedyBean.doGreedyStuff(userId);
    return result.getInt();
  }
  void setGreedyBean(GreedyBean greedyBean) { this.greedyBean = greedyBean; }
}
然后在我的JSF页面中:

<h:outputText value="#{myPageBean.firstGreedyStuffStat}"/>
<h:outputText value="#{myPageBean.secondGreedyStuffStat}"/>

我如何重构它,使其只需一次调用
GreedyBean::dogreedestuff
,而不用自己实现缓存机制?如果JSF不能做到这一点,那么这么说是一个有效的答案

注意事项:

  • 我对JSF几乎一无所知:我只修复了这一个bug,然后继续我通常的其他任务
  • 我们使用Spring进行注入,我尝试在JSF注释中翻译这些内容。如果有错误,请原谅我
  • 正如@JasperdeVries提到的,我不能将调用放入
    MyPageBean
    @PostConstruct
    ,因为数据不是最新的。结果应在请求时更新,而不是在会话开始时更新。我理解这个原则,并会执行它,尽管在这种情况下它对我没有帮助
根据“解释”,我需要添加一个新的请求范围bean:

GreedyBean.java

@ApplicationScoped
class GreedyBean {
  Result doGreedyStuff(String userId) {
    ... // Takes lots of machine resources and time.
  }
}
@RequestScoped
class MyPageRequestBean {
  // Beans
  MyPageBean myPageBean;
  GreedyBean greedyBean;

  // Data
  String firstGreedyStat;
  int secondGreedyStat;

  @PostConstruct
  public void init() {
    Result result = greedyBean.doGreedyStuff(myPageBean.getUserId());
    firstGreedyStat = result.getString();
    secondGreedyStat = result.getInt();
  }

  String getFirstGreedyStat() { return firstGreedyStat; }
  int getSecondGreedyStat() { return secondGreedyStat; }

  void setMyPageBean(MyPageBean myPageBean) { this.myPageBean = myPageBean; }
  void setGreedyBean(GreedyBean greedyBean) { this.greedyBean = greedyBean; }
}
MyPageBean.java(应该重命名为关于会话的内容,而不是页面)

MyPageRequestBean.java

@ApplicationScoped
class GreedyBean {
  Result doGreedyStuff(String userId) {
    ... // Takes lots of machine resources and time.
  }
}
@RequestScoped
class MyPageRequestBean {
  // Beans
  MyPageBean myPageBean;
  GreedyBean greedyBean;

  // Data
  String firstGreedyStat;
  int secondGreedyStat;

  @PostConstruct
  public void init() {
    Result result = greedyBean.doGreedyStuff(myPageBean.getUserId());
    firstGreedyStat = result.getString();
    secondGreedyStat = result.getInt();
  }

  String getFirstGreedyStat() { return firstGreedyStat; }
  int getSecondGreedyStat() { return secondGreedyStat; }

  void setMyPageBean(MyPageBean myPageBean) { this.myPageBean = myPageBean; }
  void setGreedyBean(GreedyBean greedyBean) { this.greedyBean = greedyBean; }
}
myPage.xhtml

<h:outputText value="#{myPageRequestBean.firstGreedyStuffStat}"/>
<h:outputText value="#{myPageRequestBean.secondGreedyStuffStat}"/>


可能与@JasperdeVries重复一个显著的区别是提到了范围,我想。我不能把它们放在会话bean的
@PostConstruct
中,因为这会占用太多时间,而且如果会话持续时间太长,数据可能会过时…如果您需要数据被请求范围限定,为什么不将其移到请求范围的bean中?@JasperdeVries hmmm。。。因为我不知道它的存在(而且在我正在修复的应用程序中似乎没有任何请求范围的bean)。谢谢你,我想我现在可以从更好的角度看JSF了!没问题,很高兴我能帮忙