PDA

View Full Version : Spring web.xml and Multiple Singletons


pauldeason
Apr 4th, 2008, 09:09 AM
Hi,

I have a problem that Spring seems to be instantiating multiple instances of singletons. My web.xml config is as follows:

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListe ner</listener-class>
</listener>
<servlet>
<description>Spring MVC Dispatcher Servlet</description>
<display-name>DispatcherServlet</display-name>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>


It seems the ContextLoaderListener creates them first and then the DispatcherServlet also instantiates new versions of the same beans, even though they are all singletons.

If I remove the ContextLoaderListener then I only get one instance. However, for some legacy code I need to use the WebApplicationContextUtils.getRequiredWebApplicati onContext(servletContext); method which seems to require it.

I would have thought that the DispatcherServlet would just inherit the beans loaded by the listener. Does anybody know how to get round this, or alternatively access the WebApplicationContext without having the ContextLoadListener declared in the web.xml.

Any help greatly appreciated.

Thanks

wpoitras
Apr 4th, 2008, 09:30 AM
So the beans are declared in one XML file that is included once, but are created multiple times? Could you debug it and set a breakpoint in the contstructor of the object that is getting created multiple times.

My understanding is that the xxx-servlet.xml Spring context is a child of the WebApplicationContext and should only get created once. Perhaps there is something else going on that debugging would reveal.

pauldeason
Apr 4th, 2008, 09:37 AM
Hi Bill,

Yep the beans are only defined once in the XML file but I have multiple instances created. I tried debugging the constructor of the object being created multiple times and each time it is being created by Spring, and as far as I can see, once by the ContextLoadListener and once by the DispatcherServlet.

I don't know if it's possible the two cross-over on start-up or something so both try and create an instance as the other one hasn't finished. I'm guessing as I really am at a loss.

But definately when I remove the ContextLoadListener does the problem go away. But I need to access the ApplicationContext from legacy servlets and I believe I need the ContextLoadListener for this.

Thanks

Chris Davies
Apr 4th, 2008, 09:51 AM
Hi Paul,

Out of interest, in your DispatcherServlet's XML file, are you <import .../>'ing your applicationContext.xml? I think that this will cause the behaviour you're describing... If you're not, then at least it's one explanation to scratch off the whiteboard. =)

pauldeason
Apr 4th, 2008, 09:56 AM
Hi Chris,

That's exactly what I'm doing! Do you know why this would cause that? And if so the best way to resolve it? I tried removing the import but then the application can't seem to find the beans in the applicationContext.xml.

I'm relatively new to this so not sure how/why this is causing it.

Thanks!

Marten Deinum
Apr 4th, 2008, 10:21 AM
All xml files you load (either by declaring them or importing them) are loaded in an ApplicationContext. So your ContextLoaderListener loads the applicationContext.xml and your DispatcherServlets loads them again due to the import.

So you end up with 2 instances.


I tried removing the import but then the application can't seem to find the beans in the applicationContext.xml.

Your application doesn't start or in your ide?

pauldeason
Apr 4th, 2008, 10:46 AM
Thanks. Actually both, the IDE doesn't like it, but more importantly when I start Tomcat the Spring initialisation fails for the spring-servlet.xml as it can't find inject beans declared in the applicationContext.xml.

Any ideas?! :confused:

pauldeason
Apr 4th, 2008, 11:12 AM
Hey guys, not to worry think it's sorted. A while ago when I set up DWR I followed an example that told me to put

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</context-param>

Into my web.xml. So the reason the applicationContext.xml wasn't being loaded was this property overrode it and the ContextLoader was loading my spring-servlet.xml twice.

Thanks very much for your help guys, wouldn't have solved that without your advice.