在SpringMVC和SpringBoot里,使用Java类进行配置的操作是很常见的操作了,其配置可大致分两类:
(小提一下@Configuration注解,在类上使用@Configuration注解时,标明这是一个配置类,相当于一个spring的.xml配置文件)
1. 普通配置
在一个类上使用@Configuration注解进行bean操作,例如导入其它jar中的bean,在类方法里进行一顿操作后再返回bean。
@Configuration
public class MyConfig{
@Bean
public Object getBean() {
Object o = new Object();
// 这里是一波很复杂的操作
return o;
}
}
2. web配置
除了使用在类上使用@Configuration外,类还继承了特定的接口或者类,用于进行MVC的配置,如添加拦截器,静态资源映射。
public class MyConfig extends WebMvcConfigurationSupport {
/**
* 配置静态资源路径
* @param registry
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
// registry.addResourceHandler("").addResourceLocations("");
super.addResourceHandlers(registry);
}
}
WebMvcConfigurer、WebMvcConfigurationSupport、WebMvcConfigurerAdapter这三个东西是最常用的类或接口,也是最让新手懵逼的,可能你百度一篇帖子说继承这个类实现那个方法就可以怎么样怎么样。有时候你会发现两个不同的项目相似的功能,你继承这个没用又实现了那个有用。下面来分析一下这三个的异同点。
- WebMvcConfigurationSupport
Support,支持的意思,是实现mvc配置的支持类,是spring官方的一个标准样例,实现了ApplicationContextAware, ServletContextAware 接口进行了mvc必要的配置。其中的很多方法用了@Bean注解,如下面的方法就往spring容器中添加了处理器映射器,但是类本身并不使用@Configuration注解,意思很明显了,spring希望开发者去继承这个类并给它加上@Configuration,然后进行自己的配置。
public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
/*
* 省略部分代码
*/
/**
* Return a {@link RequestMappingHandlerMapping} ordered at 0 for mapping
* requests to annotated controllers.
*/
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping(
ContentNegotiationManager mvcContentNegotiationManager,
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
mapping.setOrder(0);
mapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
mapping.setContentNegotiationManager(mvcContentNegotiationManager);
mapping.setCorsConfigurations(getCorsConfigurations());
/*
* 省略部分代码
*/
}
这种方式取代了开发者在xml中原本要添加处理器映射器、处理器适配器等的一系列操作。
- WebMvcConfigurer
WebMvcConfigurer定义了一系列跟mvc配置相关的接口,下面是Spring5.x.x的版本,所有的方法都是default,在Spring5.x.x之前,并没有default实现(貌似是5,反正4的好多版本都没过时),所以才有了WebMvcConfigurerAdapter的出现
@Deprecated
public interface WebMvcConfigurer {
/**
* 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
*/
default void configurePathMatch(PathMatchConfigurer configurer) {
}
/**
* Configure content negotiation options.
*/
default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
}
/*
* 省略部分代码
*/
}
- WebMvcConfigurerAdapter
WebMvcConfigurerAdapter是WebMvcConfigurer接口的抽象实现,
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
}
/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
}
/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
}
/*
* 省略部分代码
*/
}
因为Spring5.x.x之后WebMvcConfigurer的方法都改成defualt的了,所以WebMvcConfigurerAdapter也就过时了。
总结
- 任何时候继承WebMvcConfigurationSupport进行web配置都可以,但是因为有些mvc配置只需要配置一次,所以这种方式没必要使用。
- 进行mvc配置也可以实现WebMvcConfigurer接口或继承WebMvcConfigurerAdapter类都是可行的,spring5.x.x版本之后直接实现WebMvcConfigurer接口即可。这种方式配置较为灵活,按需配置,固定配置交给WebMvcConfigurationSupport进行即可。
- 注意使用xml和Java类同时进行配置时的一些冲突和上下文问题