Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scoped Spring events possible?

The Spring event mechanism supports publishing application events and listening to these events within Spring components via the @EventListener annotation. However, I cannot find anything about sending events within a specific scope in the documentation. My specific need for Vaadin is:

  • in context of a user interaction, send an event (e.g. logged-in event)
  • this event should only be consumed by beans in same @UIScope, i.e. other user UIs shouldn't be effected

Is that possible? NOTE: This is not really specific to Vaadin. I could also ask how it would be done with Spring web mvc request scope.

like image 453
Steffen Harbich Avatar asked Jul 18 '18 07:07

Steffen Harbich


People also ask

How many bean scopes are supported by Spring?

Beans can be defined to be deployed in one of a number of scopes: out of the box, the Spring Framework supports exactly five scopes (of which three are available only if you are using a web-aware ApplicationContext ). Scopes a single bean definition to a single object instance per Spring IoC container.


1 Answers

TL;DR : I think it already works as you wanted it

Long version :

The documentation is somewhat unclear about this, but having tried a simple test :

A controller that publishes events :

@Controller
public class FooController {
    @Autowired
    private ApplicationEventPublisher publisher;

    @GetMapping("/fireEvent")
    public void fireEvent() {
        publisher.publishEvent(new FooEvent(this));
    }
}

And a scoped bean that listens :

@Scope(value = WebApplicationContext.SCOPE_REQUEST)
@Component
public class FooListener {
    @EventListener(FooEvent.class)
    public void listen() {
         System.out.println("I'm listening. PS : I am "+this.toString());
    }
}

And when running two concurrent requests, only the listener scoped to the the same httprequest gets the event.


My interpretation (without having looked at it really deeply, so take it with a grain of salt) :

It seems to me that the ApplicationEventMulticaster's ListenerRetriever uses the BeanFactory to get the beans that were previously registered as listeners (by their names). And obviously, the factory will return a bean in the current scope.

like image 85
Jeremy Grand Avatar answered Oct 09 '22 11:10

Jeremy Grand