I have a problem with my Spring MVC application where my @Service classes are being created twice. I found few threads discussing this issue and most of the time it's related to have the <context:component-scan />
defined both in the Application and also Servlet Context. But in my case I have all the configuration in the Application Context file and the Servlet Context conf file is empty. I'm including the web.xml
and the applicationContext.xml
files.
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
<tx:annotation-driven />
<mvc:annotation-driven />
<task:annotation-driven />
<context:component-scan base-package="my.app" />
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:resources mapping="/assets/**" location="/WEB-INF/assets/" />
<mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>
<bean id="templateResolver"
class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".html" />
<property name="characterEncoding" value="UTF-8" />
<property name="templateMode" value="HTML5" />
<property name="cacheable" value="false" />
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<property name="additionalDialects">
<set>
<bean class="org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect"/>
</set>
</property>
</bean>
<bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
<property name="characterEncoding" value="UTF-8" />
<property name="order" value="1" />
<property name="viewNames" value="thymeleaf/*" />
</bean>
<mvc:interceptors>
<!-- Changes the locale when a 'locale' request parameter is sent; e.g.
/?locale=de -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="cookieName" value="myCookie" />
<property name="defaultLocale" value="sk_SK" />
</bean>
<import resource="spring/spring-security.xml"/>
<import resource="spring/data-source.xml" />
<import resource="spring/lang-source.xml"/>
<import resource="spring/data-properties.xml"/>
<import resource="spring/data-managers.xml" />
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
<session-config>
<session-timeout>300</session-timeout>
</session-config>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>SetCharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
If you use spring mvc. There will be two context in your application. the spring context which is based on applicationContext.xml and the appServlet-servlet.xml(the name is based on your servlet name appServlet).
When the spring context init, it will component-scan your package defined in applicationContext.xml. It is the first time your service created. Then when you use DispatcherServlet, it will create a spring context. If you have appServlet-servlet.xml, it is based on this. if else, it will component-scan all your classpath. It is the second time your service created.
If you don't want it, you can write it in your applicationContext.xml:
<context:component-scan base-package="my.app">
<context:exclude-filter type="annotation"expression="org.springframework.stereotype.Controller" />
</context:component-scan>
And then you should create appServlet-servlet.xml and write component-scan like this:
<context:component-scan base-package="my.app" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
So you can hold all your compontent and service in your spring context. And spring mvc will just hold the controller.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.