2012-03-26 20 views
7

Estoy un poco confundido acerca de cuál usar en la siguiente situación:entendimiento cdi Instancia <> y .get() vs @Inject

Supongamos que el servlet crea una aplicación que se encarga de sesión HTTP del usuario, y la aplicación es la siguiente:

public class Application extends AbstractHTTPApplication { 

@Inject 
private Instance<MainView> mainView; 

public void setupApplication() { 
    this.setView(mainView.get()); 
} 

Más tarde tengo una @SessionScoped frijol SSB que quiero para inyectar en frijol de cada usuario:

@SessionScoped 
public class SSB {} 

Ahora , Cuando intenté un habitual @Inject SSB ssb; como un campo en MainView, no lo consigo una nueva SSB para cada usuario:

public class MainView { 

@Inject 
private SSB usersSSB; 

    public someMethod() { 
     usersSSB.doSomething(); 
     System.identityHashCode(usersSSB); 
    } 
} 

de pruebas con dos usuarios, consigo el misma instancia de usersSSB en sesiones de ambos usuarios. No pensé que esto fuera posible ... pensé, dado que SSB es SessionScoped, se otorgará uno nuevo a cada sesión de usuario, y no importa dónde esté @Inject ed, se referirá a que user's SSB.

En cambio, he intentado:

public class MainView { 

@Inject 
private Instance<SSB> usersSSB; 

    public someMethod() { 
     usersSSB.get().doSomething(); 
     System.identityHashCode(usersSSB.get()); 
    } 
} 

Ahora se informa de un diferente usersSSB para cada usuario, por fin.

¿Qué está pasando aquí? Cuando llamo al usersSSB.get() más tarde en cada sesión de usuario, ¿devolverá el usersSSB.get()ese mismo bean para ese mismo usuario cada vez?

Funciono en Glassfish 3.1.2.

algo más de información

se está inyectando la clase de aplicación en el servlet en un nuevo HttpServletRequest:

public abstract class AbstractCdiApplicationServlet extends 
    AbstractApplicationServlet { 
@Inject 
protected Instance<ApplicationWrapper> wrapper; 

@Override 
protected Application getNewApplication(HttpServletRequest request) 
     throws ServletException { 
    return wrapper.get().getApplication(); 
} 
...etc etc 

Y el ApplicationWrapper es un grano SessionScoped:

@SuppressWarnings("serial") 
@SessionScoped 
public class ApplicationWrapper implements Serializable { 
@Inject 
private AbstractCdiApplication application; 

public AbstractCdiApplication getApplication() { 
    return application; 
} 
} 

Doesn Esto no significa que llamar al @Inject SSB usersSSB en cualquier lugar de MainView (o cualquier objeto dentro de la sesión de ese usuario) debería darme ese bean con ámbito de sesión del usuario, y siempre ese mismo bean con ámbito de sesión, para cada sesión de usuario? Significado: diferentes usuariosSSB para diferentes usuarios, porque cada usuario tiene una sesión diferente.

Después de todo, la Application sí mismo es un bean SessionScoped, inyectado en y unido a sesión HTTP del usuario por el método de la servlet getNewApplication? Quiero decir, es el objeto Aplicación el que inyecta y conecta la clase MainView, después de todo, ¿verdad? Así que eso significa que MainView es un bean con ámbito de sesión, ¿no?

Estoy tratando de descubrir cómo funciona todo esto, supongo. ¡Gracias por la ayuda!

+0

Eso es muy extraño. ¿Tienes esta muestra disponible para probar? – LightGuard

+0

Para ser sincero, no tengo un manejo lo suficientemente sólido como para hacer un caso de prueba simple ... ¿Hay algún arquetipo de maven funcional que lo inicie con un servlet http creando una aplicación para cada nueva sesión? Podría usar eso para construir un proyecto de prueba y publicarlo. –

Respuesta

5

Esto sucederá porque '@Inject Instancia <>' es dinámica obtenida a diferencia de '@Inject'

Si lo hace '@Inject' en frijol ApplicationScoped continuación, se obtiene inyección de una sola vez por lo que en frijol ApplicationScoped será este se obtiene misma referencia para todos los usuarios

Si llama .get() en '@Inject Instancia <>' después hacer referencia a SSB dinámicamente cada vez que se llama a .get()

Más acerca de la inyección se puede leer aquí: http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html/injection.html

+0

He agregado más información estimulada por su comentario, Krzusztof. ¿No debería '@ Inject' en un beans SessionScoped (MainView) darle el mismo objeto a ese usuario, siempre? ¿Y debería ese '@ Inject' dar un * objeto * diferente a un usuario diferente, ya que están en una sesión diferente? –

+1

Lo que realmente obtienes es un proxy que hará la búsqueda del recurso correcto cada vez. – LightGuard

+1

¿No debería @Inject dar un proxy al recurso correcto también? –