JSF Managed Bean自动创建?

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

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

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

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

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

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

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

你可以根据需要将它包装在一个帮助器方法中,这样就不必进行转换(JSF男孩没有利用generics和evaluateExpressionGetClass参数):

 public static  T findBean(String managedBeanName, Class 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 findBean(String managedBeanName) { FacesContext context = FacesContext.getCurrentInstance(); return (T) context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", Object.class); } 

可以用作:

 Bean bean = findBean("bean"); 

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

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

这个解决方案怎么样:

 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参数。

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

   requestBean lifetime.RequestBean request  cachedAsset lifetime.ExpensiveBean #{expensiveBean}   

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

问题:将使用

FacesContext context = FacesContext.getCurrentInstance();

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

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