Pregunta

Considere un ejemplo de aplicación web basada en JSF hello1 del tutorial oficial con constructor adicional en bean administrado.El seguimiento index.xhtml faceta

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

y frijol administrado modificado 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;
    }
}

Hay dos constructores públicos.Implementemos esta aplicación en el servidor y enviemos la solicitud inicial, escriba el nombre en inputText y haga clic submit.Hay una solicitud de devolución de datos después submit hacer clic.Por lo tanto, como está escrito en tutroial, tenemos la siguiente subfase de la fase de ejecución:

  1. La vista de la aplicación se construye o restaura.
  2. Se aplican los valores del parámetro de solicitud.
  3. Las conversiones y validaciones se realizan para los valores de los componentes.
  4. Los beans administrados se actualizan con los valores de los componentes.
  5. Se invoca la lógica de la aplicación.

¿En qué fase se creará la instancia del bean administrado?

¿Qué constructor se invocará para la creación de esta instancia y por qué?No entiendo como se puede observar desde el index.xhtml código.

¿Fue útil?

Solución

¿En qué fase se creará la instancia del bean administrado?

Nadie específicamente.Se construye por primera vez cuando una expresión EL arbitraria necesita hacer referencia al bean administrado por primera vez mientras la instancia del bean no está presente en su alcance.Esto no depende de ningún evento de caras en particular.Esto puede ser durante la fase de vista de restauración (la primera fase), pero también puede ser igual de bueno durante la fase de respuesta de renderizado (la última fase) o cualquier otra fase intermedia.

Todo esto depende de cómo y dónde se hace referencia al bean en el contexto EL a través de #{bean.xxx} en la vista (o mediante programación en el modelo).Generalmente no deberías preocuparte por esto.JSF (específicamente EL) al menos no lo construirá antes de lo necesario para construir, procesar o representar correctamente la vista.


¿Qué constructor se invocará para la creación de esta instancia y por qué?

El constructor predeterminado, por supuesto.Porque la especificación de Javabeans así lo dice.Todos los demás constructores nunca son utilizados por la instalación de beans administrados JSF/CDI.

Incluso entonces, no deberías preocuparte por los constructores.Será mejor que realices la inicialización en un @PostConstruct método anotado en lugar de en un constructor.Es decir, cuando el bean es administrado por un marco de administración de bean que utiliza servidores proxy, como CDI, se puede llamar al constructor predeterminado con más frecuencia de la deseada.


No entiendo cómo se puede observar desde el código index.xhtml.

Simplemente ponga un punto de interrupción en el constructor, @PostConstruct, o cualquier método getter/setter relevante y ejecute el proyecto en modo de depuración.Una vez que llegue al punto de interrupción, examine la pila de llamadas.Las clases y métodos involucrados generalmente tienen nombres que se autodocumentan.A continuación se muestra un ejemplo de cómo puede verse la pila de llamadas cuando se utiliza @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 
    ...

Comience desde abajo (he eliminado todas las líneas después FacesServlet.service ya que generalmente son irrelevantes) y lea de abajo hacia arriba.El RenderResponsePhase.execute indica que se ejecuta durante la fase de respuesta de renderizado.El TextInstruction.write dice que ocurrió durante la escritura del resultado de EL en el texto de plantilla así <p>#{bean.something}</p>.El resto es simplemente cómo la implementación CDI Weld encuentra y crea una instancia del proxy y cómo, a su vez, crea una instancia de la referencia real del bean.

Si sucediera durante una fase diferente, en lugar de RenderResponsePhase.execute he visto por ejemplo UpdateModelValuesPhase.execute etcétera.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top