@ManagedProperty - 将一个请求范围的bean注入另一个请求范围的bean

时间:2011-04-13 11:17:59

标签: jsf jsf-2 code-injection

我有 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将其注入另一个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()方法应该在表单提交时返回一个值。上述注射方法是否可行?

1 个答案:

答案 0 :(得分:9)

我认为SearchBean.input将绑定到input field

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

这样的事情:

<h:inputText value="#{searchBean.input}" />

如果是,那么这将为null:

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

但是,假设已经设置了一个值,则在调用此方法时它不会为null:

public String Submit() {
    return null;
}

Image from Richard Hightower's JSF for nonbelievers: The JSF application lifecycle

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

原因在于JSF生命周期的工作原理:

  1. 首次解析#{searchBean...}时发现不存在:
    • bean被实例化
    • 执行任何依赖注入(在这种情况下没有任何依赖注入)
    • 调用@PostConstruct方法
    • 将bean放入范围
  2. 假设Apply Request Values and Validations阶段成功,则在Update Model Values阶段调用SearchBean.setInput(String)
  3. SearchBean.Submit()在Invoke Application阶段调用
  4. 此过程在JSF specification

    中定义

    现在,如果直接从参数映射中注入SearchBean.input,则在@PostConstruct期间它不会为空:

    @ManagedProperty(value = "#{param.someParamName}")
    private String input;
    

    但是,这没有任何真正的优势 - 您正在跳过任何输入验证,并且您不能使用SearchBean.input作为字段绑定,因为它将在更新模型值阶段被覆盖。 / p>

    SearchBean.Submit()方法是您执行搜索的应用程序逻辑应该去的地方。