java JSF 托管 Bean 自动创建?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2050309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JSF Managed Bean auto-create?
提问by rat
Is it possible to have a JSF managed bean be automatically created?
是否可以自动创建 JSF 托管 bean?
For example I have several session scoped beans. Sometimes it becomes necessary to access these instances in code (rather than just in JSF) this is done by:
例如,我有几个会话范围的 bean。有时需要在代码中(而不仅仅是在 JSF 中)访问这些实例,这是通过以下方式完成的:
PageBean pageBean = (PageBean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("pages");
However if no page has already been visited which calls to '#{pages}' this resolves to null ... is there anyway to get JSF to create a bean when the scope 'begins'? So in this case ideally when a user session begins the 'pages' bean would be instantiated in the session immediately?
但是,如果没有访问过调用 '#{pages}' 的页面,这将解析为 null ... 无论如何要让 JSF 在范围“开始”时创建一个 bean?那么在这种情况下,理想情况下,当用户会话开始时,“页面”bean 将立即在会话中实例化?
回答by BalusC
Use Application#evaluateExpressionGet()instead. It will create bean when not done yet.
使用Application#evaluateExpressionGet()来代替。它会在尚未完成时创建 bean。
FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().evaluateExpressionGet(context, "#{bean}", Bean.class);
Where "bean"is the managed bean name and Bean.classis the appropriate backing bean class.
哪里"bean"是托管 bean 名称,Bean.class是适当的支持 bean 类。
You can if necessary wrap this up in a helper method so that casting is unnecessary (the JSF boys didn't take benefit of generics and the Classparameter in evaluateExpressionGet):
如有必要,您可以将其封装在一个辅助方法中,这样就不需要强制转换(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));
}
which can be used as:
可以用作:
Bean bean = findBean("bean", Bean.class);
Or without the type, but with a @SuppressWarnings:
或者没有类型,但有一个@SuppressWarnings:
@SuppressWarnings("unchecked")
public static <T> T findBean(String managedBeanName) {
FacesContext context = FacesContext.getCurrentInstance();
return (T) context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", Object.class);
}
which can be used as:
可以用作:
Bean bean = findBean("bean");
Update: the above is by the way JSF 1.2 specific. Here's the way for JSF 1.1 or older, using the currently deprecatedApplication#createValueBinding():
更新:以上是 JSF 1.2 特定的方式。这是 JSF 1.1 或更早版本的方法,使用当前已弃用的Application#createValueBinding():
FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().createValueBinding("#{bean}").getValue(context);
回答by Vic
What about this solution:
这个解决方案怎么样:
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;
}
By this way you can even avoid the Bean.class parameter.
通过这种方式,您甚至可以避免 Bean.class 参数。
回答by McDowell
One mechanism is to inject the bean into the bean you want to refer to into another bean, as demonstrated with expensiveBeanhere:
一种机制是将 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>
This isn't very "lazy", but it can be convenient.
这不是很“懒惰”,但它可以很方便。
回答by Sean
Question: will using
问题:会用
FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().evaluateExpressionGet(context, "#{bean}", Bean.class);
FacesContext 上下文 = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().evaluateExpressionGet(context, "#{bean}", Bean.class);
cause a new Bean to be instantiated each time the code runs through these statements? Or will it simply refer to the same instance initially created?
每次代码运行这些语句时都会导致一个新的 Bean 被实例化?或者它只是指最初创建的同一个实例?

