23

I have a Spring ApplicationListener bean registered to listen for ContextRefreshed events. For some odd reason though, I get two calls to the onApplicationEvent(ContextRefreshedEvent) method at the completion of the context initialization. Is this normal behavior or is it indicative of a problem with my configuration? I'm using Jetty 8 for my Servlet container.

My relevant web.xml configuration is as follows

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/config/spring/spring-config.xml</param-value>
</context-param>
<servlet>
    <servlet-name>Spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-mapping>
    <servlet-name>Spring</servlet-name>
    <url-pattern>/service/*</url-pattern>
</servlet-mapping>

Thanks!

Andre
  • 1,601
  • 3
  • 15
  • 15

4 Answers4

28

Even though you did not specify a contextConfigLocation for your DispatcherServlet it still creates a child context and the second refreshed event is for that context. Use event.getApplicationContext() to find out which context the event is for.

sourcedelica
  • 23,940
  • 7
  • 66
  • 74
  • 1
    That was it! Using either the `id` or `displayName` property of the ApplicationContext I can now distinguish between the two events. – Andre May 29 '11 at 13:06
  • 5
    Or if you @Autowire the appContext (or implement ApplicationContextAware) you can compare that appContext versus the one in the event. – sourcedelica May 29 '11 at 23:32
  • @Andre A noob's question: How to access ID or displayName from ContextRefreshedEvent? – Piyush Joshi Nov 27 '15 at 14:39
  • Figured it out. By casting ContextRefreshedEvent.getSource() to ApplicationContext and then calling getDisplayName()/getId() on that. – Piyush Joshi Nov 27 '15 at 14:48
2

it happened to me as well, on a different event-listener. (ApplicationListener<AuthenticationFailureBadCredentialsEvent>)

I suspected the ContextLoaderListener, and when I removed the declaration from the web.xml, the app was working properly. Then I had to figure out what is its purpose, of the ContextLoaderListener...

Role/Purpose of ContextLoaderListener in Spring?

the interesting answer there is:

ContextLoaderListener is optional. Just to make a point here: you can boot up a Spring application without ever configuring ContextLoaderListener ...just the basic minimum web.xml with DispatcherServlet

Community
  • 1
  • 1
OhadR
  • 8,276
  • 3
  • 47
  • 53
1

It looks like bug.

https://jira.springsource.org/browse/SPR-6589

If you are using 3.0 try it on the latest available release which is 3.05.

danny.lesnik
  • 18,479
  • 29
  • 135
  • 200
1

I had this problem too but fixed it. I was injecting the dataSource into my DAO (and instantiating a JdbcTemplate with it)....but I also had a Spring bean configured for JDBCTemplate.

I should have been injecting my DAO with the jdbcTemplate...that avoids the duplicate.

Kev
  • 11
  • 1