SpringBoot-09-拓展SpringMVC

拓展Spring MVC介绍

Spring Boot 摒弃了传统 xml 配置文件,通过配置类(标注 @Configuration 的类,相当于一个 xml 配置文件)以 JavaBean 形式进行相关配置。

Spring Boot 对 Spring MVC 的自动配置可以满足我们的大部分需求,但是我们也可以通过自定义配置类(标注 @Configuration 的类)并实现 WebMvcConfigurer 接口来定制 Spring MVC 配置,例如拦截器、格式化程序、视图控制器等等。

SpringBoot 1.5 及以前是通过继承 WebMvcConfigurerAdapter 抽象类来定制 Spring MVC 配置的,
但在 SpringBoot 2.0 后,WebMvcConfigurerAdapter 抽象类就被弃用了,改为实现 WebMvcConfigurer 
接口来定制 Spring MVC 配置。

WebMvcConfigurer 是一个基于 Java 8 的接口,该接口定义了许多与 Spring MVC 相关的方法,其中大部分方法都是 default 类型的,且都是空实现。因此我们只需要定义一个配置类实现 WebMvcConfigurer 接口,并重写相应的方法便可以定制 Spring MVC 的配置。

参考博客:地址

官方文档

If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.

编写一个@Configuration注解类,并且类型
要为WebMVCConfigurer,还不能写@EnableWebMVC注解,我们自己去写一个,我们新建一个包叫config,写一个类MyMvcConfig;

  1. MyMvcConfig
//要实现WebMvcConfigurer接口
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //浏览器发送/test,就会跳转test页面
        registry.addViewController("/test").setViewName("test");
    }
}

2.在resources/templates创建一个login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h1>登录页面</h1>
</body>
</html>

启动Spring Boot发现运行出现错误

 	cannot resolve MVC view
	不能解析MVC的视图

解决方案:

导入thymeleaf依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

声明版本

	<properties>
		<java.version>1.8</java.version>
		<thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
		<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
	</properties>

再次启动主启动类

在这里插入图片描述


分析一下拓展SpringMVC的原理

  1. 找到我们的WebMvcAutoConfiguration,里面有一个类WebMvcAutoConfigurationAdapter
@Configuration(proxyBeanMethods = false)
	@Import(EnableWebMvcConfiguration.class)
	@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })
	@Order(0)
	public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {

  1. 发现有一个EnableWebMvcConfiguration类,点击查看
	public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware
  1. 找到父类DelegatingWebMvcConfiguration

@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

	private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();

	//从容器中获取所有的webmvcConfiguruers
	@Autowired(required = false)
	public void setConfigurers(List<WebMvcConfigurer> configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.configurers.addWebMvcConfigurers(configurers);
		}
	}
	/.../
  1. 我们可以在这个类中去寻找一个我们刚才设置的viewController当做参考,发现它调用了一个
	protected void addViewControllers(ViewControllerRegistry registry) {
		this.configurers.addViewControllers(registry);
	}


  1. 我们点进去addViewControllers()方法查看
	public void addViewControllers(ViewControllerRegistry registry) {
		//添加WebMvcConfigurer的每一个委托
		for (WebMvcConfigurer delegate : this.delegates) {
			delegate.addViewControllers(registry);
		}
		//将所有的WebMvcConfigurer相关配置一起调用,包括我们自己配置的
	}

结论: 所有的WebMvcConfigurer都会起作用,不止Spring自己的配置类,还有我们的配置类也会被调用。


全面接管Spring MVC

官方文档

		If you want to take complete control of Spring MVC
		you can add your own @Configuration annotated with 	@EnableWebMvc.

全面接管即:Spring Boot 对SpringMVC的自动配置不需要了,所有都是我们自己去配置,只需要在我们的配置类添加@EnableWebMvc即可生效。

在一些特殊情况下,我们才会全面接管Spring MVC,全面接管之后,Spring Boot 对Spring MVC的自动配置将完全失效。

1.在MyMvcConfig配置类上标注@EnableWebMvc


package com.liang.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@EnableWebMvc
//要实现WebMvcConfigurer接口
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //浏览器发送/test,就会跳转test页面
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/index.html").setViewName("login");
    }
}
  1. 启动 Spring Boot,在浏览器地址栏输入“http://localhost:8080/”访问登录页,结果如下图。
    在这里插入图片描述
  2. 浏览器地址栏输入“http://localhost:8080/public/hello.html”,结果为下图
    4.

我们知道,Spring Boot能够访问位于静态资源文件的静态文件,这是Spring Boot 对Spring MVC 的默认自动配置中定义的,当我们全面接管Spring MVC后,Spring Boot 对Spring MVC的默认配置都会失效,此时再访问静态资源文件夹中的静态资源就会报404错误。

思考
为什么加了一个注解,自动配置就失效了?

  1. 点击EnableWebMvc注解
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

2.继续点击DelegatingWebMvcConfiguration类,找到父类WebMvcConfigurationSupport

public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport
  1. 回到我们的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 {

从而知道了Spring Boot 全面接管的原理,导入@EnableWebMvc,实质上是导入了WebMvcConfiguration组件让WebMvc自动配置类失效了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值