JSF Managed Bean自动创建?

时间:2010-01-12 16:07:23

标签: java jsf managed javabeans

是否可以自动创建JSF托管bean?

例如,我有几个会话范围的bean。有时需要在代码中访问这些实例(而不仅仅是在JSF中),这可以通过以下方式完成:

PageBean pageBean = (PageBean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("pages");

但是,如果没有访问过调用'#{pages}'的页面,那么这会解析为null ...无论如何都要让JSF在范围'开始'时创建一个bean?那么在这种情况下,理想情况下,当用户会话开始时,'pages'会立即在会话中实例化bean吗?

4 个答案:

答案 0 :(得分:27)

请改用Application#evaluateExpressionGet()。它还会在尚未完成时创建bean。

FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().evaluateExpressionGet(context, "#{bean}", Bean.class);

其中"bean"是托管bean名称,Bean.class是适当的支持bean类。

如果需要,您可以使用辅助方法将其包装起来,这样就不需要进行转换(JSF男孩没有利用泛型和Class中的evaluateExpressionGet参数):

public static <T> T findBean(String managedBeanName, Class<T> beanClass) {
    FacesContext context = FacesContext.getCurrentInstance();
    return beanClass.cast(context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", beanClass));
}

可以用作:

Bean bean = findBean("bean", Bean.class);

或者没有类型,但有@SuppressWarnings

@SuppressWarnings("unchecked")
public static <T> T findBean(String managedBeanName) {
    FacesContext context = FacesContext.getCurrentInstance();
    return (T) context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", Object.class);
}

可以用作:

Bean bean = findBean("bean");

更新:以上是JSF 1.2特有的方式。以下是使用当前已弃用 Application#createValueBinding()的JSF 1.1或更早版本的方式:

FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().createValueBinding("#{bean}").getValue(context);

答案 1 :(得分:3)

这个解决方案怎么样:

public static Object getBean(String beanName)
{          
    Object returnObject = FacesContext.getCurrentInstance().getELContext().getELResolver().getValue(FacesContext.getCurrentInstance().getELContext(), null, beanName);  
    if (returnObject == null)  
        System.out.println("Bean with name " + beanName + " was not found. Check the faces-config.xml file if the given bean name is ok.");          
    return returnObject;
}

通过这种方式,您甚至可以避免使用Bean.class参数。

答案 2 :(得分:0)

一种机制是将bean注入要引用到另一个bean的bean中,如expensiveBean所示:

  <managed-bean>
    <managed-bean-name>requestBean</managed-bean-name>
    <managed-bean-class>lifetime.RequestBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
      <property-name>cachedAsset</property-name>
      <property-class>lifetime.ExpensiveBean</property-class>
      <value>#{expensiveBean}</value>
    </managed-property>
  </managed-bean>

这不是很“懒惰”,但它很方便。

答案 3 :(得分:0)

问题:将使用

  

FacesContext context =   FacesContext.getCurrentInstance();

     

Bean bean =(Bean)   context.getApplication()。evaluateExpressionGet(上下文,   “#{bean}”,Bean.class);

每次代码运行这些语句时都会导致新的Bean被实例化?或者它只是引用最初创建的同一个实例?