-
Notifications
You must be signed in to change notification settings - Fork 38.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
@EventListener annotated bean cannot be removed from the ApplicationEventMulticaster #26638
Comments
This is consistent with the whole annotation model I am afraid. Message listeners (JMS, Rabbit, Kafka, etc.), scheduled methods, event listeners all add an aspect to the annotated method that represents its registration. If you want to be able to remove a listener at runtime, you should create it programmatically IMO. Can you share a bit more about your use case? |
We are building an event-based modulith. Modules are currently separated by different Java packages, are deployed within the same Spring (Boot) context, and - to enforce loose coupling - communicate with each other using ApplicationEvents. This works all surprisingly well, but we want to test our modules in isolation. I know that we could fire up different Spring contexts for the different tests and mock all non-relevant modules, but this is rather heavyweight and will slow down our tests considerably compared to firing up the Spring Boot context just once before the whole test suite runs. So the intention was to dynamically disable all EventListeners of modules not relevant for a particular test, to avoid side-effects. We btw. successfully went down this route by subclassing Spring's |
Posted an answer on SO with the current workaround by subclassing Spring's |
Thanks for sharing more details. I am not keen to register a bean for every annotated method, it looks quite invasive and unnecessary. Besides, it really is an implementation details. This would also add a number of beans to the context for the sole purpose of what you're asking for. Rather than working on the multicaster level, I wonder if building the feature in the listener itself wouldn't be better. I don't know if you're using I've flagged for team attention to see what the rest of the team thinks. |
After a quick chat with Juergen we agreed that the asymmetry in the API is annoying and we'd like to do something about it. We'd like to explore an option where an |
Thanks for that, that is good news. I was also thinking, that you don't have to register the listeners as extra beans and that an identifier of some sort would be enough: You just have to extend the listener lookup in Regarding your other suggestions: These options were on the table and they probably would work, but they are mere workarounds and we honestly don't want to bloat our production code just for testing purposes. |
I've introduced an I hope this works for your use case, e.g.: |
I've revised this a bit to only expose the This means that a downcast will be necessary, I hope that's still not too bad:
|
…lled up from tx) Includes removeApplicationListeners(Predicate) method in ApplicationEventMulticaster. Closes spring-projectsgh-26638
Affects: 2.4.3
According to the JavaDoc of the
ApplicationEventMulticaster
I was expecting to be able to remove and/or add ApplicationListeners at runtime.This currently does not work for
@EventListener
annotated methods, which apparently lead to aApplicationListenerMethodAdapter
instance at runtime.Would be great, if we could remove this listener as well, either by
multicaster.removeApplicationListener()
, ormulticaster.removeApplicationListenerBean()
I've included a small demo app with a failing test to illustrate what I'm trying to achieve:
event-sample.zip
The text was updated successfully, but these errors were encountered: