In welcher Phase wird eine verwaltete Bean erstellt und welcher Konstruktor wird verwendet

StackOverflow https://stackoverflow.com//questions/20035681

  •  21-12-2019
  •  | 
  •  

Frage

Betrachten Sie ein Beispiel für eine JSF-basierte Web-App hello1 aus dem offiziellen Tutorial mit Zusatzkonstruktor in verwalteter Bean.Das folgende index.xhtml facelet

<html lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>Facelets Hello Greeting</title>
    </h:head>
    <h:body>
        <h:form>
            <h:graphicImage url="#{resource['images:duke.waving.gif']}" 
                            alt="Duke waving his hand"/>
            <h2>Hello hui, my name is Duke. What's yours?</h2>
            <h:inputText id="username"
                         title="My name is: "
                         value="#{hello.name}"
                         required="true"
                         requiredMessage="Error: A name is required."
                         maxlength="25" />
            <p></p>
            <h:commandButton id="submit" value="Submit" action="response">
            </h:commandButton>
            <h:commandButton id="reset" value="Reset" type="reset">
            </h:commandButton>
        </h:form>
        <div class="messagecolor">
            <h:messages showSummary="true" 
                        showDetail="false"
                        errorStyle="color: #d20005" 
                        infoStyle="color: blue"/>
        </div>
    </h:body>
</html>

und modifizierte verwaltete Bohne Hello.java

package javaeetutorial.hello1;


import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class Hello {

    private String name;

    public Hello() {
    }
    public Hello(String name){
        this.name=name;
    }

    public String getName() {
        return name;
    }

    public void setName(String user_name) {
        this.name = user_name;
    }
}

Es gibt zwei öffentliche Konstrukteure.Lassen Sie uns diese App auf dem Server bereitstellen und die erste Anfrage senden, geben Sie den Namen ein inputText und klicken Sie auf submit.Es gibt eine Postback-Anfrage nach submit klicken.Daher haben wir, wie in tutroial geschrieben, die folgende Unterphase der Ausführungsphase:

  1. Die Anwendungsansicht wird erstellt oder wiederhergestellt.
  2. Die Werte der Anforderungsparameter werden angewendet.
  3. Konvertierungen und Validierungen werden für Komponentenwerte durchgeführt.
  4. Verwaltete Beans werden mit Komponentenwerten aktualisiert.
  5. Anwendungslogik wird aufgerufen.

In welcher Phase wird eine Instanz einer verwalteten Bean erstellt?

Welcher Konstruktor wird für diese Instanzerstellung aufgerufen und warum?Ich verstehe nicht, wie es von der beobachtet werden kann index.xhtml Codes.

War es hilfreich?

Lösung

In welcher Phase wird eine Instanz einer verwalteten Bean erstellt?

Niemand speziell.Es wird zum ersten Mal erstellt, wenn ein beliebiger EL-Ausdruck zum ersten Mal auf die verwaltete Bean verweisen muss, während die Bean-Instanz nicht in ihrem Gültigkeitsbereich vorhanden ist.Dies ist nicht von einem bestimmten Faces-Ereignis abhängig.Dies kann während der Wiederherstellungsphase der Ansicht (der ersten Phase) sein, aber dies kann auch während der Renderreaktionsphase (der letzten Phase) oder jeder anderen Phase dazwischen genauso gut sein.

Dies hängt alles davon ab, wie und wo die Bean im EL-Kontext referenziert wird über #{bean.xxx} in der Ansicht (oder programmgesteuert im Modell).Sie sollten sich darüber im Allgemeinen keine Sorgen machen.JSF (speziell EL) wird es zumindest nicht früher als nötig erstellen, um die Ansicht ordnungsgemäß zu erstellen, zu verarbeiten oder zu rendern.


Welcher Konstruktor wird für diese Instanzerstellung aufgerufen und warum?

Der Standardkonstruktor natürlich.Weil die Javabeans-Spezifikation das sagt.Alle anderen Konstruktoren werden niemals von der von JSF / CDI verwalteten Bean-Einrichtung verwendet.

Selbst dann sollten Sie sich keine Sorgen um Konstrukteure machen.Sie sollten die Initialisierung besser in einem durchführen @PostConstruct annotierte Methode statt in einem Konstruktor.Wenn die Bean nämlich von einem Bean-Management-Framework verwaltet wird, das Proxys wie CDI verwendet, kann der Standardkonstruktor häufiger als gewünscht aufgerufen werden.


Ich verstehe nicht, wie es aus dem Index beobachtet werden kann.xhtml-Code.

Setzen Sie einfach einen Haltepunkt in den Konstruktor, @PostConstruct, oder eine beliebige relevante Getter / Setter-Methode und führen Sie das Projekt im Debug-Modus aus.Sobald der Haltepunkt erreicht ist, untersuchen Sie den Aufrufstapel.Die beteiligten Klassen und Methoden haben im Allgemeinen eher selbstdokumentierende Namen.Hier ist ein Beispiel, wie der Aufrufstapel aussehen kann, wenn Sie verwenden @Named:

Daemon Thread [http-bio-8088-exec-6] (Suspended (entry into method <init> in TestBean)) 
    owns: LocalCache$StrongEntry  (id=503)  
    owns: SocketWrapper  (id=504)   
    TestBean$Proxy$_$$_WeldClientProxy.<init>() line: not available [local variables unavailable]   
    NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: not available [native method]   
    NativeConstructorAccessorImpl.newInstance(Object[]) line: 57    
    DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 45    
    Constructor.newInstance(Object...) line: 526    
    Class.newInstance() line: 374   
    NewInstanceAction.run() line: 33    
    AccessController.doPrivileged(PrivilegedExceptionAction<T>) line: not available [native method] 
    ClientProxyFactory(ProxyFactory).create(BeanInstance) line: 271 
    ClientProxyFactory.create(BeanInstance) line: 111   
    ClientProxyProvider.createClientProxy(Bean<T>, Set<Type>) line: 181 
    ClientProxyProvider.createClientProxy(Bean<T>) line: 171    
    ClientProxyProvider.access$100(ClientProxyProvider, Bean) line: 45  
    ClientProxyProvider$CreateClientProxy.load(Bean<Object>) line: 56   
    ClientProxyProvider$CreateClientProxy.load(Object) line: 52 
    LocalCache$LoadingValueReference.loadFuture(K, CacheLoader<? super K,V>) line: 3589 
    LocalCache$Segment.loadSync(K, int, LoadingValueReference<K,V>, CacheLoader<? super K,V>) line: 2374    
    LocalCache$Segment.lockedGetOrLoad(K, int, CacheLoader<? super K,V>) line: 2337 
    LocalCache$Segment.get(K, int, CacheLoader<? super K,V>) line: 2252 
    LocalCache.get(K, CacheLoader<? super K,V>) line: 3990  
    LocalCache.getOrLoad(K) line: 3994  
    LocalCache$LocalLoadingCache.get(K) line: 4878  
    LoadingCacheUtils.getCacheValue(LoadingCache<K,V>, K) line: 52  
    LoadingCacheUtils.getCastCacheValue(LoadingCache<K,V>, Object) line: 80 
    ClientProxyProvider.getClientProxy(Bean<T>) line: 187   
    WeldELResolver(AbstractWeldELResolver).lookup(BeanManagerImpl, ELContext, String) line: 110 
    WeldELResolver(AbstractWeldELResolver).getValue(ELContext, Object, Object) line: 91 
    WeldApplication$LazyBeanManagerIntegrationELResolver(ForwardingELResolver).getValue(ELContext, Object, Object) line: 49 
    CompositeELResolver.getValue(ELContext, Object, Object) line: 67    
    DemuxCompositeELResolver._getValue(int, ELResolver[], ELContext, Object, Object) line: 176  
    DemuxCompositeELResolver.getValue(ELContext, Object, Object) line: 203  
    AstIdentifier.getValue(EvaluationContext) line: 72  
    ValueExpressionImpl.getValue(ELContext) line: 185   
    WeldValueExpression.getValue(ELContext) line: 50    
    ELText$ELTextVariable.writeText(ResponseWriter, ELContext) line: 227    
    ELText$ELTextComposite.writeText(ResponseWriter, ELContext) line: 150   
    TextInstruction.write(FacesContext) line: 85    
    UIInstructions.encodeBegin(FacesContext) line: 82   
    UIInstructions(UILeaf).encodeAll(FacesContext) line: 207    
    HtmlBody(UIComponent).encodeAll(FacesContext) line: 1899    
    UIViewRoot(UIComponent).encodeAll(FacesContext) line: 1899  
    FaceletViewHandlingStrategy.renderView(FacesContext, UIViewRoot) line: 451  
    MultiViewHandler.renderView(FacesContext, UIViewRoot) line: 131 
    ConversationAwareViewHandler(ViewHandlerWrapper).renderView(FacesContext, UIViewRoot) line: 337 
    RenderResponsePhase.execute(FacesContext) line: 120 
    RenderResponsePhase(Phase).doPhase(FacesContext, Lifecycle, ListIterator<PhaseListener>) line: 101  
    LifecycleImpl.render(FacesContext) line: 219    
    FacesServlet.service(ServletRequest, ServletResponse) line: 647 
    ...

Beginne unten (ich habe danach alle Zeilen entfernt FacesServlet.service da diese im Allgemeinen irrelevant sind) und von unten nach oben lesen.Der RenderResponsePhase.execute gibt an, dass es während der Renderantwortphase ausgeführt wird.Der TextInstruction.write sagt, dass es beim Schreiben des Ergebnisses von EL in Vorlagentext wie folgt aufgetreten ist <p>#{bean.something}</p>.Der Rest ist nur, wie die CDI-Implementierungsschweißung den Proxy findet und instanziiert und wie er wiederum die tatsächliche Bean-Referenz instanziiert.

Wenn es in einer anderen Phase passiert wäre, würden Sie stattdessen RenderResponsePhase.execute habe zum Beispiel gesehen UpdateModelValuesPhase.execute und so weiter.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top