You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
have a prototype bean "A" which uses @Transactional and expects constructor arguments to be provided using org.springframework.beans.factory.BeanFactory.getBean(String, Object...)
the bean doesn't need to use @EventListener
start the context
expected
context starts
if "A" is the only bean (or if nothing uses "A"), the bean is not instantiated at all
observed
EventListenerMethodProcessor wants to know whether "A" is annotated with @EventListener
it calls applicationContext.getType("A")
applicationContext (or rather InfrastructureAdvisorAutoProxyCreator) sees @Transactional ...
... so sth like A$$EnhancerBySpringCGLIB$$8e7e447 is returned
EventListenerMethodProcessor.getTargetClass sees the bean class is kind of SpringProxy, so...
it instantiates the bean, but obviously not providing required arguments to constructor
Even if the bean was possible to instantiate at this point, it just does not seem right to instantiate a bean just to check its type. The instantiation can read some configuration data form database and thus be expensive, etc.
Or, when world is not perfect and not everything is a bean, it may fail.
Or, if the bean is a singleton supposed to be exposed to non-Spring-world on a static field, the bean may check it's exposed at most once.
thanks for prioritizing this and scheduling for next release.
In the meantime, I found a workaround:
<beanid="org.springframework.context.event.internalEventListenerProcessor"class="java.lang.String">
<constructor-argvalue="Disable EventListenerMethodProcessor / @EventListener support due to #18103; TODO: remove once we're on Spring 4.2.2" />
</bean>
<!-- Now context:annotation-config won't register the EventListenerMethodProcessor -->
<context:annotation-config />
You can register your own EventListenerMethodProcessor bean with name org.springframework.context.event.internalEventListenerProcessor that overrides afterSingletonInstantiated to do nothing and you should be fine.
It turns out that, overall, we don't really benefit from introspecting target classes behind proxies: We're only doing it for validation purposes, trying to find out whether the target class has an @EventListener annotation that gets suppressed through a non-annotated proxy interface. Since this is arguably something an IDE should be doing instead, we're simply not bothering anymore as of 4.2.2, always just looking at the proxy signature now (like in other places within the framework).
Piotr Findeisen opened SPR-13526 and commented
steps to reproduce
<context:annotation-config />
EventListenerMethodProcessor
A
" which uses@Transactional
and expects constructor arguments to be provided usingorg.springframework.beans.factory.BeanFactory.getBean(String, Object...)
@EventListener
expected
A
" is the only bean (or if nothing uses "A
"), the bean is not instantiated at allobserved
EventListenerMethodProcessor
wants to know whether "A
" is annotated with@EventListener
applicationContext.getType("A")
applicationContext
(or ratherInfrastructureAdvisorAutoProxyCreator
) sees@Transactional
...A$$EnhancerBySpringCGLIB$$8e7e447
is returnedEventListenerMethodProcessor.getTargetClass
sees the bean class is kind ofSpringProxy
, so...Affects: 4.2.1
Issue Links:
Referenced from: commits dbec212
1 votes, 5 watchers
The text was updated successfully, but these errors were encountered: