Archie Cobbs opened SPR-9387 and commented
I have some object which need to receive some ApplicationEvents that are sent around in my application.
However, these objects have a lifecycle that does not match with the lifecycle of normal beans in the application context (their lifecycle is shorter).
Therefore, I have these beans marked @Configurable, and they are ApplicationContextAware so they can get a reference to the application context (which is assumed to be a ConfigurableApplicationContext.
Then, when they "start" they register as listeners for application events via ConfigurableApplicationContext.addApplicationListener(). However, when they "stop" there is no way for them to unregister themselves as listeners, because there is no corresponding method ConfigurableApplicationContext.removeApplicationListener().
So this request is simply to add ConfigurableApplicationContext.removeApplicationListener().
If there is some more elegant way to do what I'm trying to do please let me know. But just from the face of it, it seems weirdly asymmetrical to have a public addFooListener() method without a corresponding removeFooListener() method.
Thanks.
Affects: 3.1.1
Issue Links:
- #14027 Support DisposableBean on prototype and @Configurable beans using weak references
1 votes, 4 watchers
Comment From: spring-projects-issues
Archie Cobbs commented
Additional info: even though these @Configurable beans implement ApplicationListener, they are not automatically registered with the event multicaster, instead triggering this warning in AbstractApplicationContext.java:
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
addApplicationListener((ApplicationListener<?>) bean);
}
else if (flag == null) {
if (logger.isWarnEnabled() && !containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.put(beanName, Boolean.FALSE);
}
That is why they have to be manually registered as listeners.
So this is kind-of a Catch-22 situation.
By the way, this issue relates to #9922, which is marked Resolved, but is it really? It seems like the code above means that it's not really resolved.
Also: I accidentally set the Component to SpringAOP instead of SpringCore, but don't have permission to edit it... sorry.
Comment From: spring-projects-issues
Archie Cobbs commented
Related to this. There is an opportunity for a little API cleanup:
* Why not let ConfigurableApplicationContext extend ApplicationEventMulticaster? Right now there are two separate interfaces declaring an addApplicationListener() method.
* ApplicationEventMulticaster still needs some genericization, i.e., methods should take parameters of type ApplicationListener<?> instead of ApplicationListener
* We have both ApplicationEventPublisher.publishEvent() and ApplicationEventMulticaster.multicastEvent(), both doing the same thing. Seems like these methods should have the same name, and ApplicationEventMulticaster should just extend ApplicationEventPublisher.
Comment From: spring-projects-issues
Bulk closing outdated, unresolved issues. Please, reopen if still relevant.
Comment From: archiecobbs
Bulk closing outdated, unresolved issues. Please, reopen if still relevant.
... except Github won't let me reopen it...
Comment From: sbrannen
This feature was also considered in conjunction with the initial implementation for #25616.
Comment From: rstoyanchev
Scheduling for 6.0 with a chance to explore a backport to 5.3.x.
Comment From: archiecobbs
Woo-hoo! Just in time for it's 10th birthday on Sunday :)
Seriously, this is why I love Spring - most projects would never bother to fix a 10 year old minor feature request.