我有这个 SearchBean :

@ManagedBean(name = "searchBean")
@RequestScoped
public class SearchBean implements Serializable
{
    private String input = null;

    // getter methods
    public String getInput() {
        return input;
    }

    // setter method
    public void setInput(String input) {
        this.input = input;
    }

    public String Submit() {
        return null;
    }
}

我可以使用@ManagedProperty 将它注入(inject)到另一个 bean 中吗?例如:
@ManagedBean(name = "bookBean")
@RequestScoped
public class BookBean implements Serializable
{
    @ManagedProperty(value = "#{searchBean}")
    private SearchBean searchBean;

    @PostConstruct
    public void init()
    {
       System.out.println("Value: " + searchBean.getInput());
    }

    public SearchBean getSearchBean() {
       return searchBean;
    }

    public void setSearchBean(SearchBean searchBean) {
       this.searchBean = searchBean;
    }
}

还有 Facelet (search.xhtml):
<h:form id="formSearch">
   <h:commandButton value="Search" action="#{searchBean.Submit}" />
</h:form>

更新 :我通过 search.xhtml 组件将 book.xhtml 插入到 ui:insert 中,如下所示:
<h:form id="formBooks">
   <ui:insert name="search">
      <ui:include src="/templates/common/search.xhtml"/>
   </ui:insert>
</h:form>

上面的 searchBean.getInput() 方法应该返回一个作为表单提交结果的值。以上注入(inject)方法可行吗?

最佳答案

我假设 SearchBean.input 将绑定(bind)到 input field :

public class SearchBean implements Serializable {
    private String input = null;

像这样的东西:
<h:inputText value="#{searchBean.input}" />

如果是这样,那么这将为空:
@PostConstruct
public void init()
{
   System.out.println("Value: " + searchBean.getInput());
}

但是 ,假设已经设置了一个值,调用这个方法时它不会为空:
public String Submit() {
    return null;
}



图片来自 Richard Hightower 的 JSF for nonbelievers: The JSF application lifecycle

原因在于 JSF 生命周期的工作方式:
  • 当首次解析 #{searchBean...} 发现不存在时:
  • bean 实例化
  • 执行任何依赖注入(inject)(在这种情况下没有任何依赖注入(inject))
  • @PostConstruct 方法被调用
  • 将 bean 放入作用域
  • 假设 Apply Request Values 和 Validations 阶段成功,在 Update Model Values 阶段调用 SearchBean.setInput(String)
  • SearchBean.Submit() 在 Invoke Application 阶段被调用

  • 这个过程在 JSF specification 中定义。

    现在,如果 SearchBean.input 是直接从参数映射中注入(inject)的,那么在 @PostConstruct 期间它不会为空:
    @ManagedProperty(value = "#{param.someParamName}")
    private String input;
    

    但是,这没有任何真正的优势 - 您正在跳过任何输入验证,并且不能使用 SearchBean.input 作为字段绑定(bind),因为它将在更新模型值阶段被覆盖。
    SearchBean.Submit() 方法是执行搜索的应用程序逻辑应该去的地方。

    关于jsf - @ManagedProperty - 将一个请求范围的 bean 注入(inject)另一个请求范围的 bean,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5648299/

    10-11 08:22