Spring beans application is duplicated

I am developing a spring application using version 3.1.2 using tomcat 7 as a servlet manager. I noticed that beans are created twice, and I'm not sure how to prevent this. I understand that the problem is somewhere in my web.xml or application context, but I could not find the source of duplication.

From the tomcat logs on startup, I see the following (paraphrasing for a space):

May 24, 2013 9:33:03 AM org.springframework.web.context.ContextLoader initWebApplicationContext INFO: Root WebApplicationContext: initialization started May 24, 2013 9:33:03 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing Root WebApplicationContext: startup date [Fri May 24 09:33:03 CDT 2013]; root of context hierarchy May 24, 2013 9:33:03 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/kpi-reporter-servlet.xml] May 24, 2013 9:33:03 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.s pringframework.beans.factory.support.DefaultListableBeanFactory@ df9978: defining beans [...]; root of factory hierarchy May 24, 2013 9:33:04 AM org.springframework.web.context.ContextLoader initWebApplicationContext INFO: Root WebApplicationContext: initialization completed in 1260 ms May 24, 2013 9:33:04 AM org.springframework.web.servlet.FrameworkServlet initServletBean INFO: FrameworkServlet 'kpi-reporter': initialization started May 24, 2013 9:33:04 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing WebApplicationContext for namespace 'kpi-reporter-servlet': startup date [Fri May 24 09:33:04 CDT 2013]; parent: Root WebApplicationContext May 24, 2013 9:33:04 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/kpi-reporter-servlet.xml] May 24, 2013 9:33:04 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.s pringframework.beans.factory.support.DefaultListableBeanFactory@ 2821db: defining beans [...]; parent: org.s pringframework.beans.factory.support.DefaultListableBeanFactory@ df9978 

Here are my web.xml and application context settings:

web.xml

 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>kpi-reporter</display-name> <servlet> <servlet-name>kpi-reporter</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>kpi-reporter</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> <url-pattern>*.gif</url-pattern> <url-pattern>*.js</url-pattern> <url-pattern>*.png</url-pattern> </servlet-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/kpi-reporter-servlet.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app> 

KPI reporter-servlet.xml:

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="."/> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans> 

If I delete the statement in the kpi-reporter-servlet.xml file, the beans will not be defined at all. If I translate the context statement into web.xml (along with the required import), it will still be defined twice. I suspect that somehow web.xml is called twice during startup.

I checked the webapps directory and I have only one file and directory, the .war file used to deploy the application, and the directory into which it was unpacked.

Other .war applications developed by me also have this behavior, although they have similar xml files associated with them.

Does anyone know why this might happen? I'm at a standstill.

Thanks in advance, Max

+4
source share
2 answers

You can comment on the context-param section, something like this:

 <!--context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/kpi-reporter-servlet.xml</param-value> </context-param--> 

Or rename kpi-reporter-servlet.xml to another, and change the value of param-value context-param accordingly.

Spring doc says:

After initializing the DispatcherServlet, Spring MVC looks for a file named [servlet-name] - servlet.xml ...

So, in your case, it is like kpi-reporter-servlet.xml is declared twice.

+5
source

Sring initializes two application contexts here:

ContextLoaderListener creates an application context with beans contained in the file that your context-param tag refers to:

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

This is the context of the root (or parent) application.

Your DispatcherServlet then searches for a file called SERVLET-NAME-servlet.xml and creates another application context with beans defined in the file. This application context will have the "root" application context as the parent. Here your servlet name is "kpi-reporter", so it loads all the beans defined in "kpi-reporter-servlet.xml".

So, if you do not need to use ContextLoaderListener, delete it. If you need this, change the file name (for example: kpi-reporter-context.xml) and specify the empty kpi-reporter-servlet.xml file that will be loaded by DispatcherServlet.

0
source

Source: https://habr.com/ru/post/1482592/


All Articles