java - que - ¿JSF Managed Bean crea automáticamente?
que es un bean en netbeans (4)
¿Es posible crear automáticamente un bean gestionado JSF?
Por ejemplo, tengo varios beans de ámbito de sesión. A veces es necesario acceder a estas instancias en el código (en lugar de solo en JSF) esto se hace mediante:
PageBean pageBean = (PageBean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("pages");
Sin embargo, si ya no se ha visitado ninguna página que llame a ''# {pages}'', esto se resuelve en nulo ... ¿hay alguna forma de que JSF cree un bean cuando el alcance ''comience''? Entonces, en este caso, idealmente, cuando comienza una sesión de usuario, el bean ''pages'' se instanciaría en la sesión de inmediato?
Un mecanismo es inyectar el frijol en el frijol que desea consultar en otro frijol, como se demostró con expensiveBean
aquí:
<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>
Esto no es muy "flojo", pero puede ser conveniente.
Pregunta: ¿usará
FacesContext context = FacesContext.getCurrentInstance ();
Bean bean = (Bean) context.getApplication (). EvaluateExpressionGet (context, "# {bean}", Bean.class);
hacer que un nuevo Bean sea instanciado cada vez que el código se ejecuta a través de estas declaraciones? ¿O simplemente se referirá a la misma instancia inicialmente creada?
¿Qué pasa con esta solución?
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;
}
De esta forma, puedes incluso evitar el parámetro Bean.class.
Use Application#evaluateExpressionGet()
lugar. Creará frijol cuando aún no está hecho.
FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().evaluateExpressionGet(context, "#{bean}", Bean.class);
Donde "bean"
es el nombre del bean administrado y Bean.class
es la clase de bean de respaldo apropiada.
Si es necesario, puede envolver esto en un método auxiliar para que la conversión sea innecesaria (los chicos JSF no tomaron el beneficio de los genéricos y el parámetro Class
en evaluateExpressionGet
):
public static <T> T findBean(String managedBeanName, Class<T> beanClass) {
FacesContext context = FacesContext.getCurrentInstance();
return beanClass.cast(context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", beanClass));
}
que se puede usar como:
Bean bean = findBean("bean", Bean.class);
O sin el tipo, pero con @SuppressWarnings
:
@SuppressWarnings("unchecked")
public static <T> T findBean(String managedBeanName) {
FacesContext context = FacesContext.getCurrentInstance();
return (T) context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", Object.class);
}
que se puede usar como:
Bean bean = findBean("bean");
Actualización : lo anterior es por cierto JSF 1.2 específico. Aquí está el camino para JSF 1.1 o una Application#createValueBinding()
anterior, usando la Application#createValueBinding()
actualmente en desuso Application#createValueBinding()
:
FacesContext context = FacesContext.getCurrentInstance();
Bean bean = (Bean) context.getApplication().createValueBinding("#{bean}").getValue(context);