2012-10-22 8 views
5

Ich habe eine Reihe von eifrigApplicationScoped verwalteten Bohnen. Einige von ihnen werden durch die ManagedProperty Annotation in andere injiziert und bilden einen Baum von Abhängigkeiten. Jede abhängige Bohne manipuliert ihre Eltern nach der Konstruktion.Eager ApplicationScoped verwaltete Bohnen mehrfach konstruiert

Es scheint jedoch, als ob für jede Injektion eine neue Instanz erstellt wird, wodurch vorherige Manipulationen rückgängig gemacht werden. Nach meinem Verständnis sollte eine ApplicationScoped Bean nur einmal erstellt werden. Habe ich missverstanden oder warum passiert das? Ist es weil sie eifrig sind? Hier

ein Beispiel:

ParentBean.java

package example; 

import javax.annotation.PostConstruct; 
import javax.faces.bean.ApplicationScoped; 
import javax.faces.bean.ManagedBean; 

@ManagedBean(eager = true) 
@ApplicationScoped 
public class ParentBean 
{ 
    static int initCount = 0; 

    // ... 

    @PostConstruct 
    public void init() 
    { 
     ++initCount; // Will end up being between 1 and 3. Expected always 1. 

     // ... 
    } 
} 

Child1Bean.java

package example; 

import javax.annotation.PostConstruct; 
import javax.faces.bean.ApplicationScoped; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ManagedProperty; 

@ManagedBean(eager = true) 
@ApplicationScoped 
public class Child1Bean 
{ 
    @ManagedProperty("#{parentBean}") ParentBean parentBean; 

    public ParentBean getParentBean() 
    { 
     return parentBean; 
    } 

    public void setParentBean(ParentBean parentBean) 
    { 
     this.parentBean = parentBean; 
    } 

    @PostConstruct 
    public void init() 
    { 
     // manipulate parentBean 
    } 
} 

Child2Bean.java

package example; 

import javax.annotation.PostConstruct; 
import javax.faces.bean.ApplicationScoped; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ManagedProperty; 

@ManagedBean(eager = true) 
@ApplicationScoped 
public class Child2Bean 
{ 
    @ManagedProperty("#{parentBean}") ParentBean parentBean; 

    public ParentBean getParentBean() 
    { 
     return parentBean; 
    } 

    public void setParentBean(ParentBean parentBean) 
    { 
     this.parentBean = parentBean; 
    } 

    @PostConstruct 
    public void init() 
    { 
     // manipulate parentBean 
    } 
} 
+2

können Sie einen Codebeispiel geben, wie Sie es tun? –

+0

Okay, ich habe ein Beispiel hinzugefügt. – Spomf

+0

glaube nicht, dass ich etwas ändern werde, aber versuchen Sie '@ManagedProperty (value =" # {parentBean} ")', – Daniel

Antwort

0

Ich habe dieselben Probleme mit Mojarra 2.0 .x. Ich nehme an, dass dieses Problem mit Multithread-JSF-Initialisierung verbunden ist. Versuchen Sie, es durch den Parameter com.sun.faces.enableMultiThreadedStartup zu deaktivieren.

+0

Danke, aber es hatte keine Wirkung. Meine Anwendung läuft auf Mojarra 2.1.6. – Spomf

+0

Haben Sie gelöst? Ich habe das gleiche Problem –

1

Ich habe dieses Problem hoffentlich auf Tomcat 8 + Mojarra 2.2.0 gelöst. In meinem Fall habe ich Zuhörer Erklärung nur von web.xml

<listener> 
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class> 
</listener> 

Constructor scheint entfernt, sobald danach aufgerufen werden.

Über Listener Eintrag, gibt es einen Teil der BalusC Antwort von this Frage.

In jedem Fall ist die explizite Registrierung von Mojarra des ConfigureListener in web.xml eigentlich nur notwendig alte Buggy-Servern wie Glassfish v3 und Jetty zu umgehen, die den Hörer in Mojarra der TLD-Datei zu finden ist fehlgeschlagen. Bei Bereitstellung auf einem ordentlichen Server ist der gesamte Eintrag nicht erforderlich.