扩展SpringMVC

1
2
3
4
5
6
7
8
9
10
11
12
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:view-controller path="/hello" view-name="succcess"></mvc:view-controller>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/hello"/>
<bean></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>

编写一个配置类(@Configuration),是WebMvcConfigurerAdapter,不标注@EnableWebMvc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.wsx.springboothelloworld.config;

import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/wsx").setViewName("templates_hello");
}
}

原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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 {

public static final String DEFAULT_PREFIX = "";

public static final String DEFAULT_SUFFIX = "";

private static final String[] SERVLET_LOCATIONS = { "/" };

里面也是这个类,注意又个EnableWebMvcConfiguration

1
2
3
4
5
6
7
8
9
10
11
// 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 {

private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);

private final ResourceProperties resourceProperties;

静态资源映射

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
1
2
3
4
5
6
7
8
9
10
/**
* Configuration equivalent to {@code @EnableWebMvc}.
*/
@Configuration(proxyBeanMethods = false)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {

private final ResourceProperties resourceProperties;

private final WebMvcProperties mvcProperties;

从容器中获取所有的webmvcconfigurer,然后全部调用一遍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
*
* @author Rossen Stoyanchev
* @since 3.1
*/
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();


@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}

springmvc的自动配置和我们的扩展配置都会起作用

全面接管mvc

不要Springboot的mvc了,完全自己接管,使用@EnableWebMvc,那么web的自动配置全部失效,甚至静态资源都无法使用

为什么enablewebmvc就全部失效呢

1
2
3
4
5
6
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
1
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
1
2
3
4
5
6
7
8
9
@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 {

当容器中没有WebMvcConfigurationSupport的时候,自动配置才开始生效,enablewebmvc帮我们导入了这个,所以失效了

如何修改SpringBoot的默认配置

springboot先看容器中有没有用户自己配置的,如果有就用用户配置的,没有才自动配置

在springboot中有很多xxxConfiguier帮助我们扩展配置,

在骚一点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Configuration
//@EnableWebMvc
public class MyMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/wsx").setViewName("templates_hello");
}

@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
return new WebMvcConfigurerAdapter() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/wsx2").setViewName("templates_hello");
registry.addViewController("/wsx3").setViewName("templates_hello");
}
};
}
}

引入bootstrap的webjars

官网

1
2
3
4
5
6
7
<!--        bootstrap-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.0.0</version>
</dependency>

@{/webjars/bootstrap/4.0.0/css/bootstrap.css}

这个语法很好,因为当我们的项目名字变了的时候,不需要去修改所有的url,
server.context-path=/crud