Issue
I have the below Configuration class:
@Configuration
public class SomeConfig {
@Bean
public SomeBean someBean() {
if (some condition...) {
return new SomeBean();
}
return null;
}
}
public class SomeBean {
@EventListener
public void handleSomeEvent() {
// do something...
}
}
Now, if the someBean()
method returning null, and the event SomeEvent
is published, I am getting the below exception:
java.lang.IllegalStateException: The event listener method class 'com.logic.SomeBean' is not an instance of the actual bean class 'org.springframework.beans.factory.support.NullBean'. If the bean requires proxying (e.g. due to @Transactional), please use class-based proxying.
HandlerMethod details:
Bean [org.springframework.beans.factory.support.NullBean]
Method [public void com.logic.SomeBean.handleSomeEvent(com.events.SomeEvent)]
Resolved arguments:
[0] [type=com.events.SomeEvent] [value=com.events.SomeEvent[source=com.events.SomeEventPublisher@13ee1d20]]
at org.springframework.context.event.ApplicationListenerMethodAdapter.assertTargetBean(ApplicationListenerMethodAdapter.java:330) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:264) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:179) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:142) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
Why spring still know the bean SomeBean
even its method returned null?
Solution
By returning null from the bean method someBean()
, Spring create object of NullBean, and register it as the bean for SomeBean.
You should, if possible, extract the logic in "some condition..." to use Conditional annotation, to use on the method someBean()
, or to use profiling.
A work around for this, is to change the method someBean() to return an interface, lets say ISomeBean, that SomeBean will inherit from. Like that, spring will not scan the @EventListener
of SomeBean class.
Answered By - Tamir Adler
Answer Checked By - David Goodson (JavaFixing Volunteer)