32.SpringBoot学习笔记–扩展与全面接管SpringMVC
扩展 SpringMVC
原来使用 SpringMVC 配置方法:
<mvc:view-controller path="/hello" view-name="success"/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/hello"/>
<bean></bean>
</mvc:interceptor>
</mvc:interceptors>
<mvc:default-servlet-handler/>
Spring Boot 的配置方法:
If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration
class of type WebMvcConfigurer
but without @EnableWebMvc
.
参考:Spring MVC Auto-configuration
示例
既保留了 Spring Boot 的所有自动配置,也能用扩展的配置。
demo.yangxu.springboot.config.MyMvcConfig
package demo.yangxu.springboot.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//使用WebMvcConfigurer扩展SpringMVC的功能
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//浏览器发送 /yangxu 请求来到 success
registry.addViewController("/yangxu").setViewName("success");
}
}
访问 http://localhost:8080/yangxu 即跳转到 success
参考:
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter
WebMvcAutoConfiguration 是 SpringMVC 的自动配置类,在做其他自动配置时会导入 @Import(EnableWebMvcConfiguration.class)
// Defined as a nested config to ensure WebMvcConfigurer is not read when not
// on the classpath
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration
@Configuration(proxyBeanMethods = false)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {}
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#configurers
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#setConfigurers
从容器中获取所有的 WebMvcConfigurer
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
参考实现:
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#addViewControllers
@Override
protected void addViewControllers(ViewControllerRegistry registry) {
this.configurers.addViewControllers(registry);
}
org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite#addViewControllers
将所有的 WebMvcConfigurer 相关配置一起调用,容器中所有的 WebMvcConfigurer 都会一起起作用。
@Override
public void addViewControllers(ViewControllerRegistry registry) {
for (WebMvcConfigurer delegate : this.delegates) {
delegate.addViewControllers(registry);
}
}
自己写的配置类也会被调用。
效果:SpringMVC的自动配置和自己写的扩展配置都会起作用。
全面接管 SpringMVC
If you want to take complete control of Spring MVC, you can add your own @Configuration
annotated with @EnableWebMvc
, or alternatively add your own @Configuration
-annotated DelegatingWebMvcConfiguration
as described in the Javadoc of @EnableWebMvc
.
Spring Boot 对 SpringMVC 的自动配置都失效了,全都需要自己配置。在配置类中添加 @EnableWebMvc 即可。
参考:Spring MVC Auto-configuration
示例
demo.yangxu.springboot.config.MyMvcConfig
package demo.yangxu.springboot.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//使用WebMvcConfigurer扩展SpringMVC的功能
@EnableWebMvc
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//浏览器发送 /yangxu 请求来到 success
registry.addViewController("/yangxu").setViewName("success");
}
}
@EnableWebMvc 自动配置失效参考原理:
org.springframework.web.servlet.config.annotation.EnableWebMvc
@EnableWebMvc 的核心,导入了 DelegatingWebMvcConfiguration 组件,DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport。
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {}
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {}
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class):容器中没有 WebMvcConfigurationSupport 组件的时候,这个自动配置类才生效。
@EnableWebMvc 导入了 DelegatingWebMvcConfiguration 组件,而 DelegatingWebMvcConfiguration 继承于 WebMvcConfigurationSupport,DelegatingWebMvcConfiguration 实际上是 WebMvcConfigurationSupport 的一种,所以 WebMvcAutoConfiguration 自动配置类失效。
导入的 WebMvcConfigurationSupport 组件只是 SpringMVC 的基本功能。
修改 Spring Boot 的默认配置
模式:
1、Spring Boot 在自动配置组件时,先看容器中有没有用户自己配置的(@Bean、@Component),如果有就使用用户配置的,如果没有,就自动配置。如果有些组件可以有多个(如:ViewResolver),将用户配置的和默认的组合起来;
2、在 Spring Boot 中有很多的 xxxConfigurer 进行扩展配置;
3、在 Spring Boot 中有很多的 xxxCustomizer 进行定制配置。