2010-01-12 19 views
16

¿Es posible crear automáticamente un bean gestionado JSF?JSF Managed Bean auto-create?

Por ejemplo, tengo varios beans de ámbito de sesión. A veces se hace necesario acceder a estos casos en el código (en lugar de sólo en JSF) esto se hace por:

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

Sin embargo, si no hay página ya ha sido visitado, que llama a '# {páginas}' que esto se resuelva a null ... ¿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?

Respuesta

27

Use Application#evaluateExpressionGet() en su lugar. Creará frijol cuando aún no está hecho.

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

Dónde "bean" es el nombre bean gestionado y Bean.class es la clase bean de respaldo apropiado.

Puede si es necesario terminar con esto en un método de ayuda para que la fundición es innecesaria (JSF los chicos qué no tomar ventaja 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 puede ser utilizado como:

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

o sin el tipo, pero con un @SuppressWarnings:

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

que puede ser utilizado como:

Bean bean = findBean("bean"); 

actualización: lo anterior es por cierto JSF 1.2 específico. Así es el camino para JSF 1.1 o mayor, utilizando la actualidad obsoletaApplication#createValueBinding():

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

Thx para esto, mi IDE está siendo cojo con la carga de clase en esto, pero creo que es la forma correcta de hacerlo ... estúpido Eclipse WAS y está construido en libs. – rat

+0

¿ERA? Mi respuesta es, por cierto, el objetivo de JSF 1.2 (que ya tiene casi 4 años). FUE utilizado para enviar con JSF 1.1 heredado durante mucho tiempo hasta 6.1 en 2007. Voy a editar mi respuesta y agregar pronto el JSF 1.1. – BalusC

+0

WAS = servidor de aplicaciones websphere De todos modos, pensé que debía ser 1.2 dado que WAS incluye 1.1 libs y no mostraba el método como válido, aunque cambié la carga de clases y ahora está funcionando bien, gracias de nuevo: D – rat

0

Uno de los mecanismos es inyectar el grano en el frijol que desea hacer referencia a en otro bean, como se ha demostrado 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.

+0

Ya estoy usando la inyección, necesita ser más flojo en este caso, pero thx :) – rat

0

Pregunta: ¿usando

FacesContext context = FacesContext.getCurrentInstance();

grano de frijol = (Bean) context.getApplication() evaluateExpressionGet (contexto, "# {bean}", Bean.class).;

causan 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?

3

¿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 manera se puede evitar incluso el parámetro Bean.class.

+0

Esta es una buena técnica, me gusta más esta. Esto también en mención en el blog de Oleg http://ovaraksin.blogspot.com/2011/11/5-useful-methods-jsf-developers-should.html +1 –

Cuestiones relacionadas