Spring MVC – Beans loaded twice
A Spring MVC web application, noticed all the Spring’s beans are loaded twice!?
package com.mkyong.config.db;
@Configuration
public class MongoDevConfig {
private final static Logger logger = LoggerFactory.getLogger(MongoDevConfig.class);
@Bean
MongoDbFactory mongoDbFactory() throws Exception {
logger.debug("Init...... MongoDbFactory() in production mode!");
//...
return new new SimpleMongoDbFactory(mongo, "db");;
}
}
During Application startup :
2015-03-05 17:52:32 DEBUG c.m.config.MongoLiveConfig - Init...... MongoDbFactory() in production mode!
2015-03-05 17:52:32 DEBUG c.m.config.MongoLiveConfig - Init...... MongoDbFactory() in production mode!
1. Spring Configuration
Here is the Spring MVC configuration.
web.xml
<web-app>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
</web-app>
mvc-dispatcher-servlet.xml
<beans...>
<context:component-scan base-package="com.mkyong" />
<mvc:annotation-driven />
</beans>
2. Solution
Read this Spring DispatcherServlet reference to understand how Spring pick up the XML file :
Upon initialization of a DispatcherServlet, Spring MVC looks for a file named [servlet-name]-servlet.xml in the WEB-INF directory of your web application and …
In Above Spring configuration :
- The servlet
mvc-dispatcher
will loadmvc-dispatcher-servlet.xml
- And the listener
ContextLoaderListener
will loadsmvc-dispatcher-servlet.xml
again
To fix it, just renamed the servlet name mvc-dispatcher
to something else.
web.xml
<web-app>
<!-- Now it will find hello-dispatcher-servlet.xml -->
<servlet>
<servlet-name>hello-dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
In short, make sure Spring will not pick up the Spring XML configuration twice.
Ideally, contextConfigLocation should load applicationContext (called it root application context). While dispatcher servlet is belong to servlet context. Any root application-context is a configuration that are not directly related to spring mvc. From hierarchy point of view, root context cannot refer to spring bean that create in servlet-context, but in servlet context that are able to refer to any root context bean. This article is a good example shown bean loaded twice with misconfiguration. Good work
MVC_helloWorld
index.html
hello
org.springframework.web.servlet.DispatcherServlet
0
hello
*.htm
i tried the same but still it called twice
Nice! Thanks
How to handle this in Spring BOOT ?
Hi mykong, this tutorial really helped me. I have confusion regarding the memory management. Will the application use double memory (for two beans)? Upon changing the value/property of one bean runtime, will be reflected to other bean?
I like your posts as they are short and to the point. However, these days hardly anyone uses a XML configuration in Spring web app.
We’ve the same issue (beans loading twice) using @Configuration classes and AbstractAnnotationConfigDispatcherServletInitializer. Do you’ve any thoughts on how that may be happening?
This can happen if you have both in the applicationContext.xml and @EnableWebMvc declared on your WebConfiguration class. Removing the XML line should do the trick.
I your class that extends AbstractAnnotationConfigDispatcherServletInitializer methods getRootConfigClasses() and getServletConfigClasses() should return different classes and not contain same classes.
Many Thanks !. I see you’ve covered tutorials for all latest important technologies, but you’ve not created tutorials for one more latest technology which is JPA (Java Persistent API). May I request you please to create good tutorials for the same? Looking forward to your earliest possible response.
Noted, JPA and also Spring Data.
Great Observation! Yes I came accross the same issue a few years back , I dont remember what exact solution I put in then ,but your post reminds me the old days and refeshes my mind with a good solution aswell ! so thanks for that ..cheers Pronab
welcome.