是否可以自动创建JSF托管bean?
例如,我有几个会话范围的bean。有时需要在代码中访问这些实例(而不仅仅是在JSF中),这可以通过以下方式完成:
PageBean pageBean = (PageBean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("pages");
但是,如果没有访问过调用'#{pages}'的页面,那么这会解析为null ...无论如何都要让JSF在范围'开始'时创建一个bean?那么在这种情况下,理想情况下,当用户会话开始时,'pages'会立即在会话中实例化bean吗?
答案 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被实例化?或者它只是引用最初创建的同一个实例?