如果在使用SpringMVC时不希望采用XML的配置方式,而采用基于Java类的配置也是可以的。如果还希望在web.xml中配置DispatcherServlet,则需要通过init-param指定contextClass为AnnotationConfigWebApplicationContext,然后把context ConfigLocation指定为SpringMVC配置Java类的全路径名称。
<class="pl-ent">servlet> <servlet-name>spring</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.elim.spring.mvc.MvcConfiguration</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
在Java配置类中就可以按照正常的Java类配置那样定义,如下则定义了扫描com.elim.spring.mvc.controller
包下面的Class。
@ComponentScan(basePackages = "com.elim.spring.mvc.controller") public class MvcConfiguration { }
如果定义DispatcherServlet时还是指定的配置文件为XML文件,则也可以在对应的XML配置文件中定义上面的Java配置类为一个bean,效果是一样的。
之后可以在该配置类中定义一些SpringMVC配置bean,比如下面就定义了一个InternalResourceViewResolver。
@ComponentScan(basePackages = "com.elim.spring.mvc.controller") public class MvcConfiguration { @Bean public InternalResourceViewResolver newInternalResourceViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/view/"); resolver.setSuffix(".jsp"); return resolver; } }
在进行配置时也可以选择实现WebMvcConfigurer接口进行配置,或者选择继承自抽象类WebMvcConfigurerAdapter,然后重写感兴趣的方法。以下是WebMvcConfigurer的定义。
public interface WebMvcConfigurer { /** * Add {@link Converter}s and {@link Formatter}s in addition to the ones * registered by default. */ void addFormatters(FormatterRegistry registry); /** * Configure the {@link HttpMessageConverter}s to use in argument resolvers * and return value handlers that support reading and/or writing to the * body of the request and response. If no message converters are added to * the list, default converters are added instead. * @param converters initially an empty list of converters */ void configureMessageConverters(List<HttpMessageConverter<?>> converters); /** * Provide a custom {@link Validator} instead of the one created by default. * The default implementation, assuming JSR-303 is on the classpath, is: * {@link org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean}. * Leave the return value as {@code null} to keep the default. */ Validator getValidator(); /** * Configure content negotiation options. */ void configureContentNegotiation(ContentNegotiationConfigurer configurer); /** * Configure asynchronous request handling options. */ void configureAsyncSupport(AsyncSupportConfigurer configurer); /** * Helps with configuring HandlerMappings path matching options such as trailing slash match, * suffix registration, path matcher and path helper. * Configured path matcher and path helper instances are shared for: * <ul> * <li>RequestMappings</li> * <li>ViewControllerMappings</li> * <li>ResourcesMappings</li> * </ul> * @since 4.0.3 */ void configurePathMatch(PathMatchConfigurer configurer); /** * Add resolvers to support custom controller method argument types. * <p>This does not override the built-in support for resolving handler * method arguments. To customize the built-in support for argument * resolution, configure {@link RequestMappingHandlerAdapter} directly. * @param argumentResolvers initially an empty list */ void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers); /** * Add handlers to support custom controller method return value types. * <p>Using this option does not override the built-in support for handling * return values. To customize the built-in support for handling return * values, configure RequestMappingHandlerAdapter directly. * @param returnValueHandlers initially an empty list */ void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers); /** * Configure the {@link HandlerExceptionResolver}s to handle unresolved * controller exceptions. If no resolvers are added to the list, default * exception resolvers are added instead. * @param exceptionResolvers initially an empty list */ void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers); /** * Add Spring MVC lifecycle interceptors for pre- and post-processing of * controller method invocations. Interceptors can be registered to apply * to all requests or be limited to a subset of URL patterns. */ void addInterceptors(InterceptorRegistry registry); /** * Provide a custom {@link MessageCodesResolver} for building message codes * from data binding and validation error codes. Leave the return value as * {@code null} to keep the default. */ MessageCodesResolver getMessageCodesResolver(); /** * Configure simple automated controllers pre-configured with the response * status code and/or a view to render the response body. This is useful in * cases where there is no need for custom controller logic -- e.g. render a * home page, perform simple site URL redirects, return a 404 status with * HTML content, a 204 with no content, and more. */ void addViewControllers(ViewControllerRegistry registry); /** * Configure view resolvers to translate String-based view names returned from * controllers into concrete {@link org.springframework.web.servlet.View} * implementations to perform rendering with. */ void configureViewResolvers(ViewResolverRegistry registry); /** * Add handlers to serve static resources such as images, js, and, css * files from specific locations under web application root, the classpath, * and others. */ void addResourceHandlers(ResourceHandlerRegistry registry); /** * Configure a handler to delegate unhandled requests by forwarding to the * Servlet container's "default" servlet. A common use case for this is when * the {@link DispatcherServlet} is mapped to "/" thus overriding the * Servlet container's default handling of static resources. */ void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer); }
采用继承WebMvcConfigurerAdapter的方式,上面的配置可以改写为如下这样。
@ComponentScan(basePackages = "com.elim.spring.mvc.controller") public class MvcConfiguration extends WebMvcConfigurerAdapter { @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.jsp("/WEB-INF/view/", ".jsp"); } }
在使用Java配置时也可以在配置类上使用@EnableWebMvc
,这样SpringMVC将进行一些自动配置。具体的自动配置内容可以参考WebMvcConfigurationSupport类的定义。当然也可以选择直接继承自WebMvcConfigurationSupport,然后进行部分方法重写。
@EnableWebMvc @ComponentScan(basePackages = "com.elim.learn.spring.mvc.controller") public class MvcConfiguration extends WebMvcConfigurerAdapter { @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.jsp("/WEB-INF/view/", ".jsp"); } @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(new MappingJackson2HttpMessageConverter()); converters.add(new StringHttpMessageConverter(Charset.defaultCharset())); } }
如果希望不在web.xml文件中定义DispatcherServlet,而是完全通过程序来定义,可以选择定义一个AbstractDispatcherServletInitializer的子类,然后实现其中的抽象方法。如果是需要使用基于注解的配置,则可以直接继承AbstractAnnotationConfigDispatcherServletInitializer类。AbstractAnnotationConfigDispatcherServletInitializer中定义了三个抽象方法,getRootConfigClasses()
用来定义根配置的类,即对应根ApplicationContext的配置类,如果这个配置还是通过在web.xml中配置的则可以忽略它;getServletConfigClasses()
则对应SpringMVC配置的配置类;getServletMappings()
则用于指定需要映射的地址。以下就是自定义的一个初始化类,它会在容器启动的时候自动发现,然后进行SpringMVC的初始化工作。
public class SpringInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return null; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[]{MvcConfiguration.class}; } @Override protected String[] getServletMappings() { return new String[]{"/"}; } }
(注:本文是基于Spring4.1.0所写)