2012-03-26 7 views
7

jestem trochę mylić o których użycie w następującej sytuacji:Zrozumienie cdi Instance <> i .get() vs @Inject

Przypuśćmy, że serwlet tworzy aplikację, która obsługuje sesji HTTP użytkownika, a wniosek jest taki:

public class Application extends AbstractHTTPApplication { 

@Inject 
private Instance<MainView> mainView; 

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

Później mam @SessionScoped fasoli SSB który chcę wprowadzić do fasoli każdego użytkownika:

@SessionScoped 
public class SSB {} 

teraz Kiedy próbowałem regularne @Inject SSB ssb; jako pole w MainView, nie mam dostać nowy SSB dla każdego użytkownika:

public class MainView { 

@Inject 
private SSB usersSSB; 

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

Testowanie z dwoma użytkownikami, otrzymuję samą wystąpienie usersSSB w sesjach zarówno użytkownika. Nie sądziłem, że to było możliwe ... Pomyślałem, że ponieważ SSB jest SessionScoped, nowy zostanie podany do każdej sesji użytkownika, i bez względu na to, gdzie jest @Inject ed będzie to odnosić się do , że użytkownika SSB użytkownika.

Zamiast Próbowałem:

public class MainView { 

@Inject 
private Instance<SSB> usersSSB; 

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

Teraz donosi, że inny usersSSB dla każdego użytkownika, w końcu.

Co się tutaj dzieje? Kiedy później zadzwonię pod numer usersSSB.get() w sesji każdego użytkownika, czy usersSSB.get() zwróci tę samą fasolę dla tego samego użytkownika za każdym razem?

Używam Glassfish 3.1.2.

Niektórzy Więcej informacji

Klasa aplikacja jest wstrzykiwany do serwletu na nowym 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 

A ApplicationWrapper jest SessionScoped fasola:

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

public AbstractCdiApplication getApplication() { 
    return application; 
} 
} 

Doesn To oznacza, że ​​wywołanie @Inject SSB usersSSB w dowolnym miejscu w MainView (lub jakikolwiek obiekt w ramach sesji tego użytkownika) powinien przekazać mi komponent o tej samej szerokości, a także zawsze ten sam komponent o zakresie sesji o wartości dla sesji każdego użytkownika? Znaczenie - różni użytkownicySSB dla różnych użytkowników, ponieważ każdy użytkownik ma inną sesję.

Sam w sobie Application jest fasolką SessionScoped, wstrzykniętą i dołączoną do sesji HTTP użytkownika przez metodę serwletu getNewApplication? Chodzi mi o to, że to obiekt aplikacji wstrzykuje i przyłącza klasę MainView, prawda? Oznacza to, że MainView jest komponentem o zasięgu sesji, prawda?

Po prostu próbuję zrozumieć, jak to wszystko działa, tak myślę. Dzięki za pomoc!

+0

To bardzo dziwne. Czy ta próbka jest dostępna do testowania? – LightGuard

+0

Szczerze mówiąc, nie mam na tyle solidnego rozwiązania, aby zrobić prosty test ... Czy istnieje pracowity archetyp, który uruchomi cię z serwletem http tworzącym aplikację dla każdej nowej sesji? Mogłabym użyć tego do zbudowania projektu testowego i opublikowania go. –

Odpowiedz

5

to zdarzyć, ponieważ „@Inject Instance <>” jest dynamiczny uzyskany w przeciwieństwie do „@Inject”

Jeśli tak „” na ApplicationScoped @Inject fasoli następnie wstrzyknięcie uzyskuje się tylko raz więc w ApplicationScoped fasoli będzie to same odniesienia dla wszystkich użytkowników

Jeśli zadzwonisz .get() na „@Inject Instancji <>” następnie odwołać do SSB uzyskuje się dynamicznie za każdym razem, gdy dzwonisz .get()

Więcej o zastrzyku można przeczytać tutaj: http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html/injection.html

+0

Dodałem kilka dodatkowych informacji zainspirowanych Twoim komentarzem, Krzusztof. Czy nie powinno się zawsze "@Inject" w ziarnie SessionScoped (MainView) podawać ten sam obiekt temu użytkownikowi? A czy to "@ Inject" daje * inny * obiekt dla innego użytkownika, ponieważ są one w innej sesji? –

+1

To, co otrzymujesz, to proxy, które za każdym razem wykona wyszukiwanie właściwego zasobu. – LightGuard

+1

Czy funkcja @Inject nie powinna również podawać pełnomocnictwa do prawidłowego zasobu? –