2010-01-12 15 views
16

È possibile creare automaticamente un bean gestito JSF?JSF Managed Bean crea automaticamente?

Ad esempio, ho diversi bean con scope di sessione. A volte si rende necessario per accedere a questi casi nel codice (e non solo in JSF) questo è fatto da:

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

Tuttavia, se nessuna pagina è già stato visitato, che chiama a '# {pagine}' questo risolve a NULL ... c'è comunque un modo per far sì che JSF crei un bean quando l'oscilloscopio 'inizia'? Quindi, in questo caso, idealmente quando inizia una sessione utente, il bean "pagine" verrà immediatamente istanziato nella sessione?

risposta

27

Utilizzare invece Application#evaluateExpressionGet(). Creerà il bean quando non è ancora finito.

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

Dove "bean" è il nome bean gestito e Bean.class è la classe supporto bean appropriato.

È possibile, se necessario, avvolgere questo in un metodo di supporto in modo che casting è inutile (i ragazzi JSF fatto non prendere vantaggio dei farmaci generici e il parametro Class in evaluateExpressionGet):

public static <T> T findBean(String managedBeanName, Class<T> beanClass) { 
    FacesContext context = FacesContext.getCurrentInstance(); 
    return beanClass.cast(context.getApplication().evaluateExpressionGet(context, "#{" + managedBeanName + "}", beanClass)); 
} 

che può essere utilizzato come:

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

O senza il tipo, ma con una @SuppressWarnings:

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

che può essere usato come:

Bean bean = findBean("bean"); 

Aggiornamento: quanto sopra è dal modo JSF 1.2 specifico. Ecco la strada per JSF 1.1 o più anziani, con il momento deprecatoApplication#createValueBinding():

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

Thx per questo, il mio IDE è zoppo con il caricamento della classe su questo, ma credo che sia il modo giusto di farlo ... stupido è stato eclissi e le sue librerie incorporate. – rat

+0

ERA? La mia risposta è indirizzata a JSF 1.2 (che ha già quasi 4 anni ora). È stato utilizzato per la spedizione con JSF 1.1 legacy per un tempo molto lungo, fino al 6.1 circa 2007. Modificherò la mia risposta e aggiungerò presto la JSF 1.1. – BalusC

+0

WAS = server di applicazioni webspace In ogni caso ho calcolato che deve essere 1.2 poiché WAS include 1.1 librerie e non mostrava il metodo come valido, ho cambiato il caricamento della classe in giro e ora funziona correttamente grazie ancora: D – rat

0

Un meccanismo è quello di iniettare il fagiolo nel chicco si desidera fare riferimento a in un altro bean, come dimostrato con expensiveBean qui:

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

Questo non è molto "pigro", ma può essere conveniente.

+0

Sto usando l'iniezione già, ha bisogno di essere più pigro in questo caso, ma thx :) – rat

0

Domanda: sarà usando

FacesContext context = FacesContext.getCurrentInstance();

Bean fagioli = (Bean) context.getApplication() evaluateExpressionGet (contesto, "# {} di fagioli", Bean.class).;

causa l'istanziazione di un nuovo bean ogni volta che il codice scorre attraverso queste istruzioni? O si riferirà semplicemente alla stessa istanza inizialmente creata?

3

Che dire di questa soluzione:

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; 
} 

In questo modo si può anche evitare il parametro Bean.class.

+0

Questa è una buona tecnica, mi piace di più. Questo anche nel blog Oleg http://ovaraksin.blogspot.com/2011/11/5-useful-methods-jsf-developers-should.html +1 –

Problemi correlati