我最近将我的Spring 4 MVC Web应用程序从XML配置转换为基于java的配置。执行此操作后,所有控制器都会映射两次。我觉得它与组件扫描有关,但我无法弄清楚原因。我可以发布旧的XML配置设置,如果这将有所帮助。应用程序运行正常,它只是在日志中打印两次控制器映射。
这里将它们加载到根上下文
...
INFO RequestMappingHandlerMapping - Mapped "{[/user/changePassword],methods=[POST]}" onto public org.springframework.web.servlet.ModelAndView com.rapidtest.mvc.controller.UserController.changePasswordSubmit(com.rapidtest.mvc.form.user.ChangePasswordFormBean,org.springframework.validation.BindingResult) throws java.lang.Exception
INFO SimpleUrlHandlerMapping - Mapped URL path [/pub/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
INFO SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
INFO RequestMappingHandlerAdapter - Looking for @ControllerAdvice: Root WebApplicationContext: startup date [Thu Oct 22 16:16:24 MDT 2015]; root of context hierarchy
这里它们也被加载到消息调度程序上下文
...
INFO RequestMappingHandlerMapping - Mapped "{[/user/changePassword],methods=[POST]}" onto public org.springframework.web.servlet.ModelAndView com.rapidtest.mvc.controller.UserController.changePasswordSubmit(com.rapidtest.mvc.form.user.ChangePasswordFormBean,org.springframework.validation.BindingResult) throws java.lang.Exception
INFO SimpleUrlHandlerMapping - Mapped URL path [/pub/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
INFO SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
INFO RequestMappingHandlerAdapter - Looking for @ControllerAdvice: WebApplicationContext for namespace 'website-servlet': startup date [Thu Oct 22 16:16:28 MDT 2015]; parent: Root WebApplicationContext
这是我的web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>website</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.rapidtest.config.mvc.MVCConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>website</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.rapidtest.config.spring</param-value>
</context-param>
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.rapidtest.util.properties.ArchaiusPropertyInitializer</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.rapidtest.web.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<error-code>404</error-code>
<location>/error/404</location>
</error-page>
<error-page>
<location>/error/general</location>
</error-page>
</web-app>
这是我的java MVC配置
package com.rapidtest.config.mvc;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
@ComponentScan("com.rapidtest.mvc.controller")
public class MVCConfig extends WebMvcConfigurationSupport {
// <mvc:resources mapping="/pub/**" location="/pub/" />
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pub/**").addResourceLocations("/pub/");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
// <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
// <property name="prefix">
// <value>/WEB-INF/jsp/</value>
// </property>
// <property name="suffix">
// <value>.jsp</value>
// </property>
// </bean>
@Bean
public ViewResolver configureViewResolver() {
InternalResourceViewResolver viewResolve = new InternalResourceViewResolver();
viewResolve.setPrefix("/WEB-INF/jsp/");
viewResolve.setSuffix(".jsp");
return viewResolve;
}
// <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
@Bean(name = "multipartResolver")
public CommonsMultipartResolver getMultipartResolver() {
return new CommonsMultipartResolver();
}
}
这是我的RootConfig。我所有的其他@Configuration类都在同一个包中。
package com.rapidtest.config.spring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import com.rapidtest.util.properties.ArchaiusPropertyPlaceholderConfigurer;
@Configuration
//@ComponentScan(basePackages = {"com.rapidtest"}, useDefaultFilters=false, excludeFilters={
// @ComponentScan.Filter(type=FilterType.ANNOTATION, value={Controller.class, ControllerAdvice.class})})
@ComponentScan(basePackages = {"com.rapidtest"} )
public class RootConfig {
//<bean id="propertyConfigurer" class="com.rapidtest.util.properties.ArchaiusPropertyPlaceholderConfigurer" />
@Bean(name = "propertyConfigurer")
public static ArchaiusPropertyPlaceholderConfigurer getPropertyPlaceholder() {
return new ArchaiusPropertyPlaceholderConfigurer();
}
}
答案 0 :(得分:1)
这个
@ComponentScan(basePackages = {"com.rapidtest"} )
RootConfig
中的会扫描前缀为com.rapidtest
的所有包裹。
您的MVCConfig
课程在com.rapidtest.config.mvc
个包中。因此,它也会被RootConfig
加载的ContextLoaderListener
选中并初始化。
隔离您的包裹,以免发生这种情况。
答案 1 :(得分:0)
我能够通过忽略组件扫描中的所有@Configuration类来解决问题。
@ComponentScan(basePackages = { "com.rapidtest.*" }, excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, value = { Configuration.class })
})