2010-01-12 15 views
16

Kann eine JSF-verwaltete Bean automatisch erstellt werden?JSF Managed Bean automatisch erstellen?

Zum Beispiel habe ich mehrere Session-Bereich Bohnen. Manchmal wird es notwendig, diese Instanzen in Code für den Zugriff auf (und nicht nur in JSF) dies erfolgt durch:

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

jedoch, wenn keine Seite bereits besucht, welche Anrufe zu ‚# {Seiten}‘ dies löst auf null ... gibt es sowieso, um JSF zu veranlassen, eine Bean zu erstellen, wenn der Bereich 'beginnt'? In diesem Fall würde also idealerweise beim Start einer Benutzersitzung die Bean 'pages' sofort in der Sitzung instanziiert werden.

Antwort

27

Verwenden Sie stattdessen Application#evaluateExpressionGet(). Es wird Bean erstellen, wenn es noch nicht fertig ist.

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

Wo "bean" ist die Managed Bean Namen und Bean.class ist die geeignete Träger Bean-Klasse.

Sie können bei Bedarf wickeln diese in einer Hilfsmethode, so dass Gießen nicht erforderlich sind (die JSF Jungs nicht nehmen Nutzen von Generika und die Class Parameter 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)); 
} 

, die verwendet werden können, wie:

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

oder ohne Typ, aber mit einem @SuppressWarnings:

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

, die als verwendet werden können:

Bean bean = findBean("bean"); 

aktualisieren: das ist oben durch die Art und Weise JSF 1.2 spezifisch. Hier ist der Weg für JSF 1.1 oder älter, mit der derzeit veraltetApplication#createValueBinding():

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

Thx dafür, meine IDE ist lahm mit der Klasse laden, aber ich glaube, es ist der richtige Weg, es zu tun ... dumm WAS Eclipse und seine eingebauten Bibliotheken. – rat

+0

WAS? Meine Antwort zielt übrigens auf JSF 1.2 ab (das jetzt schon fast 4 Jahre alt ist). WAS verwendet, um mit Legacy JSF 1.1 für eine sehr lange Zeit bis mit 6.1 um 2007 zu versenden. Ich werde meine Antwort bearbeiten und die JSF 1.1 bald hinzufügen. – BalusC

+0

WAS = websphere application server Wie auch immer ich dachte, es muss 1.2 sein, da WAS 1.1 libs enthält und es die Methode nicht als gültig zeigte, änderte ich die Klassenladung herum und jetzt funktioniert es gut noch einmal danke: D – rat

0

Ein Mechanismus ist die Bohne in die Bohne Sie in eine andere Bohne beziehen möchten zu injizieren, wie mit expensiveBean hier gezeigt:

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

Dies ist nicht sehr "faul", aber es kann bequem sein.

+0

Ich benutze die Injektion bereits, muss in diesem Fall eher faul sein, aber thx :) – rat

0

Frage: wird mit

Faces context = FacesContext.getCurrentInstance();

Bean Bean = (Bean) context.getApplication(). EvaluateExpressionGet (Kontext, "# {bean}", Bean.class);

veranlassen, dass jedes Mal, wenn der Code diese Anweisungen durchläuft, eine neue Bean instanziiert wird? Oder bezieht es sich einfach auf die ursprünglich erstellte Instanz?

3

an dieser Lösung:

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

Durch diese Weise können Sie auch die Bean.class Parameter vermeiden.

+0

Dies ist eine gute Technik, ich mag das besser. Dies auch auf Oleg Blog erwähnt http://ovaraksin.blogspot.com/2011/11/5-useful-methods-jsf-developers-should.html +1 –

Verwandte Themen