2014-07-23 14 views
5

Mam potrzebę zarejestrowania osobnego detektora zdarzeń dla każdego żądania. Celem słuchacza jest złapać zdarzeń pochodzących z innych wniosków spoczynku, podczas gdy wniosek słuchacza jest zablokowany w oczekiwaniu wszystkich wymaganych zdarzeń przyjśćApplicationEventListener o ograniczonym zasięgu żądania nie może odbierać zdarzeń

Mam kodu, takich jak to:.

@Component 
// @Scope(WebApplicationContext.SCOPE_REQUEST) 
public static class WhistleEventListener implements ApplicationListener<WhistleEvent> { 
    volatile Consumer<WhistleEvent> handler; 
    @Override 
    public void onApplicationEvent(WhistleEvent we) { 
    final Consumer<WhistleEvent> h = handler; 
    if (h != null) h.accept(we); 
    } 
} 
@Autowired WhistleEventListener whistleEventListener; 

Kod ten odbiera zdarzenia, ale zaraz po odkomentowaniu adnotacji @Scope przestaje odbierać zdarzenia.

Czy obsługiwane są detektory zdarzeń aplikacji o zakresie zapytań, czy są to , które powinny działać pod? Jeśli tak, czy mogę zrobić coś, aby mój słuchacz zadziałał?

Odpowiedz

1

Podejrzewam masz niezrozumienie przypadku aplikacji wysyłający mechaniki: zdarzenie jest wywoływane przed fasoli definicje, nie fasola instancji, a każda definicja fasola zostanie rozwiązany do wystąpienia w tej chwili, w kontekście , z publikacji wydarzenia. Oznacza to, że Twoje zdarzenie zostanie wysłane tylko do komponentu o zakresie żądania, w ramach którego wydarzenie jest opublikowane, ale chcesz, aby nasłuchiści z bieżących żądań byli powiadamiani.

Ogólniej, celem zakresu jest wyodrębnienie instancji zakresu, które zawierają oddzielne instancje komponentu bean. Jeśli nie chcesz izolacji, powinieneś użyć zakresu, który nie ma osobnych instancji, na przykład zakresu aplikacji.

Oznacza to, że do wysłania zdarzenia do innych przypadkach zakresie, trzeba by zrobić wysyłając siebie, na przykład takich jak:

@Component 
public class WhistleEventMediator implements ApplicationListener<WhistleEvent> { 
    // TODO: make thread safe 
    final Set<Consumer<WhistleEvent>> consumers; 

    void subscribe(Consumer<WhistleEvent> c) { ... } 

    void unsubscribe(Consumer<WhistleEvent> c) { ... } 

    @Override public void onApplicationEvent(WhistleEvent we) { 
     // delegate to subscribed consumers 
    } 
} 

@Component 
@Scope(WebApplicationContext.SCOPE_REQUEST) 
public class WhateverBean implements Consumer<WhistleEvent> { 
    @Inject 
    WhistleEventMediator mediator; 

    @PostConstruct 
    void init() { 
     mediator.subscribe(this); 
    } 

    @PreDestroy 
    void destroy() { 
     mediator.unsubscribe(this); 
    } 

    // handle whistle event 
} 
+0

I uciekają się do tego, co ty tu przedstawić, stosując 'ConcurrentHashMap' oraz z dodatkowym problemem, że "Konsument" jest lambdą i nie należy liczyć na jego tożsamość. Potrzebuję więc wygenerować unikalny klucz do mapy. Jest brzydki, ale działa na razie. –

Powiązane problemy