springboot——7springMVC配置原理及扩展

springMVC配置原理

学习springMVC时最佳方式就是看着官方文档学习。
网址为:https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications

了解它spring web mvc 的框架的特性

那么从4.7.1. The “Spring Web MVC Framework”章节开始
它说The Spring Web MVC framework (often referred to as simply “Spring MVC”)
springMVC的灵魂就在@Controller和@RestController,还举例说明如何使用。。。

闲话不说太多。好了,接下来进入正题:Spring MVC Auto-configuration

Spring MVC Auto-configuration
// Spring Boot为Spring MVC提供了自动配置,它可以很好地与大多数应用程序一起工作。
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
// 自动配置在Spring默认设置的基础上添加了以下功能:
The auto-configuration adds the following features on top of Spring’s defaults:
// 包含视图解析器
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
// 支持静态资源文件夹的路径,以及webjars
Support for serving static resources, including support for WebJars 
// 自动注册了Converter:
// 转换器,这就是我们网页提交数据到后台自动封装成为对象的东西,比如把"1"字符串自动转换为int类型
// Formatter:【格式化器,比如页面给我们了一个2019-8-10,它会给我们自动格式化为Date对象】
Automatic registration of Converter, GenericConverter, and Formatter beans.
// HttpMessageConverters
// SpringMVC用来转换Http请求和响应的的,比如我们要把一个User对象转换为JSON字符串,可以去看官网文档解释;
Support for HttpMessageConverters (covered later in this document).
// 定义错误代码生成规则的
Automatic registration of MessageCodesResolver (covered later in this document).
// 首页定制
Static index.html support.
// 图标定制
Custom Favicon support (covered later in this document).
// 初始化数据绑定器:帮我们把请求数据绑定到JavaBean中!
Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

/*
如果您希望保留Spring Boot MVC功能,并且希望添加其他MVC配置(拦截器、格式化程序、视图控制器和其他功能),则可以添加自己
的@configuration类,类型为webmvcconfiguer,但不添加@EnableWebMvc。如果希望提供
RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义
实例,则可以声明WebMVCregistrationAdapter实例来提供此类组件。
*/
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.

// 如果您想完全控制Spring MVC,可以添加自己的@Configuration,并用@EnableWebMvc进行注释。
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

8个特性,举例进行学习即可,
1.包含了ContentNegotiatingViewResolver 和BeanNameViewResolver 的beans
也就是自带了视图解析器的意思。
我shift+shift,查找了ContentNegotiatingViewResolver 这个类

public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
		implements ViewResolver, Ordered, InitializingBean {
}
		

实现了ViewResolver接口,这个接口是这样的:

public interface ViewResolver {
	@Nullable
	View resolveViewName(String viewName, Locale locale) throws Exception;

}

那么说是不是实现了这个接口就是视图解析器呢?
在下面有这样一句话:如果您想保留这些Spring Boot MVC定制并进行更多MVC定制(拦截器、格式化程序、视图控制器和其他功能),您可以添加自己的WebMVCConfiguer类型的@Configuration类,但不要添加@EnableWebMvc。
我创建一个类进行测试:

@Configuration
public class MyMVCConfig {


    //所有的请求都会经过dispatcherServlet里面,doService,doDispatch,所有的请求和响应都会经过这里,可以在这里打一个断点观察我定义的视图解析器的有没有存在

    //如果想要自定义一些定制化的功能,只需要写这个组件,将它交给springboot,springboot就会自动装配

    @Bean
    public ViewResolver myViewResolver(){
        return new MyViewResolver();
    }

    public static class MyViewResolver implements ViewResolver {
        //实现了ViewResolver的类就被当做视图解析器
        @Override
        public View resolveViewName(String viewName, Locale locale) throws Exception {
            return null;
        }
    }
}

建一个配置类,内部静态类(自定义视图解析器),并将它注入IOC。

之前知道Springmvc中所有的配置都会走dispatherServlet中,所以我进去DispatcherServlet类中查看,有方法是doService,doDispatch。
这两个方法是mvc中所有请求必须经过的地方,在doDispatch方法添加一个断点。调试一下。
springboot——7springMVC配置原理及扩展_第1张图片
可以发现我定义的视图解析器的确被加载了。

由此可推断springboot帮我们自动装配了。

MVC扩展:转换器和格式化器

消息转换器Formatter
可以在WebMvcAutoConfigretion中找到如下适配器

		@Bean
		@Override
		public FormattingConversionService mvcConversionService() {
			Format format = this.mvcProperties.getFormat();
			WebConversionService conversionService = new WebConversionService(new DateTimeFormatters()
					.dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime()));
			addFormatters(conversionService);
			return conversionService;
		}

显而易见的,这是一个转换器,而它获取了格式format,然后将日期转换格式完成转换。
比如,看一下DateTimeFormatters类

public class DateTimeFormatters {

	...
	public DateTimeFormatters dateFormat(String pattern) {
		if (isIso(pattern)) {
			this.dateFormatter = DateTimeFormatter.ISO_LOCAL_DATE;
			this.datePattern = "yyyy-MM-dd";
		}
		else {
			this.dateFormatter = formatter(pattern);
			this.datePattern = pattern;
		}
		return this;
	}
	...
}

它的默认实现就是年月日的格式
点进getFormat()可以发现,它是WebMvcProperties的方法,这说明我们也可以在配置文件中,进行配置。还有日期类也刚好在附近

@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {
	@Deprecated
	@DeprecatedConfigurationProperty(replacement = "spring.mvc.format.date")
	public String getDateFormat() {
		return this.format.getDate();
	}

	@Deprecated
	public void setDateFormat(String dateFormat) {
		this.format.setDate(dateFormat);
	}

	public Format getFormat() {
		return this.format;
	}
}

真是顺手牵羊。

如果配置了自己的格式化方式,就会注册到Bean中生效,我们可以在配置文件中配置日期格式化的规则

spring.mvc.format.date=dd/MM/yyyy

idea中会有提示,说明可以映射到。

修改SpringBoot的默认配置

我们要做的就是编写一个@Configuration注解类,并且类型要为WebMvcConfigurer,还不能标注@EnableWebMvc注解,在官网中without是标粗的,标粗是很少见的,所以为什么不能加这个EnableWebMvc呢

我们可以加上看看会发生什么(作死的边缘疯狂试探)
也不能闭着眼去作死,看一下这个注释干了什么

@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

它导入一个类,继续点

@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
	@Autowired(required = false)
	public void setConfigurers(List configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.configurers.addWebMvcConfigurers(configurers);
		}
	}
}

这个注解:代理bean方法false?代理bean有哪些?这个方法说吧配置都加进去。

不懂,所以看源码WebMvcAutoConfiguration类

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

条件是没有它!
WebMvcConfigurationSupport这个类只是加载web的一些最基本配置,导入他会让我们的配置都失效(不是我说的,是狂老师说的)
原话是这样的:
@EnableWebMvc将WebMvcConfigurationSupport组件导入进来了;
而导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能!
在SpringBoot中会有非常多的扩展配置

全面接管即:SpringBoot对SpringMVC的自动配置不需要了,所有都是我们自己去配置!
只需在我们的配置类中要加一个@EnableWebMvc。
如果我们全面接管了SpringMVC了,我们之前SpringBoot给我们配置的静态资源映射一定会无效,测试一下。了解即可。

(看破不说破,后面是强行水完的,已经没办法全部接受了,属实能力有限)

你可能感兴趣的:(springboot,spring,boot)