SpringBoot学习大纲
一、基于SpringBoot搭建Web工程:
1.1.编码实现步骤:
a.创建SpringBoot项目
b.选中依赖:选中我们所需要的模块
1.2.SSM中的WEB开发配置与SpringBoot中WEB开发自动配置对比:
a.SSM中的WEB开发:
- 1.在
SSM 整合时,需要手动配置 Tomcat 、配置 SpringMVC、配置如何扫描包、配置字符过滤器、配置视图解析器、文件上传
等,如下图所示的配置,非常麻烦。
b.SpringBoot中的web开发:
在SpringBoot 中,存在自动配置机制,提高开发效率
- 1.导入web开发的场景:
- 2.引入场景启动器后,就引入了autoconfigure功能
- 3.@EnableAutoConfiguration注解使用@Import(AutoConfigurationImportSelector.class)批量导入组件
二、SpringBoot在Web场景下的自动配置:
2.1.Web开发相关的自动配置类:
- 1.如下是在引入web开发的场景启动器后,会找到这些全类名,然后根据这些全类名批量加载自动配置类组件到容器中
- 2.SpringBoot启动
默认加载 xxxAutoConfiguration(这些类就是自动配置类)这些类
都在如下这个org包中:
- 3.其中与web开发有关的自动配置类都在web目录中
2.2.SpringBoot对SpringMVC自动配置
a.SpringBoot对SpringMVC自动的默认配置
b.SpringBoot中对SpringMVC的定制化开发:
- 1.全自动的默认配置:
- 含义解释:保持 SpringBootMVC的默认配置,并且自定义更多的 mvc 配置,如:interceptors, formatters, view controllers 等
- 实现方式:
使用@Configuration注解添加一个 WebMvcConfigurer 类型的配置类,并不要标注 @EnableWebMvc
- 2.手动自动结合:
- 含义解释:保持 SpringBootMVC的默认配置,但要自定义核心组件实例,比如:RequestMappingHandlerMapping, RequestMappingHandlerAdapter, 或ExceptionHandlerExceptionResolver,
- 实现方式:
@Configuration 标注一个配置类,实现 WebMvcConfigurer 接口,给容器中放一个 WebMvcRegistrations 组件即可
- 3.全手动方式:
- 含义解释:全面接管 Spring MVC
- 实现方式:
@Configuration 标注一个配置类,并加上 @EnableWebMvc注解,实现 WebMvcConfigurer 接口
2.3.分析WebMvcAutoConfiguration类的源码:
a.定位SpringMVC相关的自动配置类源码:
- 1.SpringBoot中对SpringMVC功能的自动配置类是
WebMvcAutoConfiguration
b.WebMvcAutoConfiguration类源码分析:
1、WebMvcAutoConfiguration类的源码:
- 可以看到这个类上
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)、@ConditionalOnClass()、ConditionalOnWebApplication
条件注解
2、分析:WebMvcAutoConfiguration类生效条件
- 1.
@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class })
意思是在DispatcherServletAutoConfiguration、TaskExecutionAutoConfiguration(异步任务)、ValidationAutoConfiguration(数据校验)配置好了之后,WebMvcAutoConfiguration再进行配置 - 2.
@ConditionalOnWebApplication(type = Type.SERVLET)
如果是web应用就生效,类型是SERVLET、REACTIVE响应式编程 - 3.
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
:容器中有Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class这些Bean才生效,这里我们引入了web场景,所以可以判断出自动配置类是WebMvcAutoConfiguration
是生效的 - 4.
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
:容器中没有WebMvcConfigurationSupport这个Bean才生效 - 5.
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
:定义的是优先级
3、其他说明:
- 1.如果创建
xxxConfig类并实现WebMvcConfiger
,就会使WebMvcAutoConfiguration配置类失效
,因为在该类中有@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
这个注解会触发 - 2.
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
这个注解会触发的原因是我们在自定义的xxConfig类
中实现了WebMvcConfiger
,点进WebMvcConfiger
这个接口就可以知道它继承了WebMvcConfigurationSupport
,所以springboot自动帮我们配置好的webMvcAutoConfiguration就会失效,注意只是我们在xxxConfig类中重写的default失效
c.分析当webMvcAutoConfiguration生效时会自动配置什么:
c1.配置了SpringMVC兼容Rest风格的请求
- HiddenHttpMethodFilter;页面表单提交Rest请求(GET、POST、PUT、DELETE)
c2.配置了表单内容的过滤器:
- 1.可以配合HiddenHttpMethodFilter过滤器使用
- 2.表单内容Filter,GET(数据放URL后面)、POST(数据放请求体)请求可以携带数据,PUT、DELETE 的请求体数据会被忽略,使用OrderedFormContentFilter可以实现PUT、DELETE类型的请求体不被忽略
c3.配置了静态内部类:WebMvcAutoConfigurationAdapter
1、配置的静态内部类WebMvcAutoConfigurationAdapter作用:
- 静态内部类WebMvcAutoConfigurationAdapter的作用就是给容器中放了WebMvcConfigurer组件;给SpringMVC添加各种定制功能
2、介绍静态内部类WebMvcAutoConfigurationAdapter类所实现的WebMvcConfigurer接口:
====================== SpringBoot2中WebMvcAutoConfigurationAdapter类的源码===================
- 1.如下可以看到静态内部类WebMvcAutoConfigurationAdapter仅实现了WebMvcConfigurer接口
====================== SpringBoot3中WebMvcAutoConfigurationAdapter类的源码=================== - 1.如下可以看到静态内部类WebMvcAutoConfigurationAdapter实现了WebMvcConfigurer接口
- 2.ctrl + F12可以看到WebMvcConfigurer接口中的所有方法,这些抽象方法提供了配置SpringMVC底层的所有组件的入口:
- 3.下面我对接口中的抽象方法的功能进行了说明:
3、解析静态内部类WebMvcAutoConfigurationAdapter上标注的注解:
========== ==SpringBoot2中静态内部类WebMvcAutoConfigurationAdapter上标注的注解 =================
- 1.注解1 @Configuration:
在WebMvcAutoConfigurationAdapter类上有注解@Configuration
,所以说这个类是属于一个配置类
- 2.注解2 @EnableConfigurationProperties 根据
@EnableConfigurationProperties({WebMvcProperties.class,ResourceProperties.class})
可见有xxxxproperties,这说明配置文件的属性配置是和实体类xxx绑定在一起的
- 3.由下图可知:配置文件中
WebMvcProperties==spring.mvc
和ResourceProperties==spring.resources
进行了绑定
- 2.WebMvcProperties分析:
- 3.ResourceProperties分析:
========== ==SpringBoot3中静态内部类WebMvcAutoConfigurationAdapter上标注的注解 =================
- 1.@EnableConfigurationProperties注解: 根据
@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })
可见有xxxxproperties,这说明配置文件的属性配置是和实体类xxx绑定在一起的
- 2.根据如下源码可知:
WebMvcProperties对配置文件中的spring.mvc
进行了绑定
- 3.根据如下源码可知:
WebProperties对配置文件中的spring.web
进行了绑定
4、
扩展知识
:当某个配置类只有一个有参构造器的时候,有参构造器所有参数的值都会从容器中确定
这里的WebMvcAutoConfigurationAdapter配置类就是只有一个有参构造器!!!
,所以所有参数的值都会从容器中确定
ResourceProperties resourceProperties;
获取和spring.resources绑定的所有的值的对象WebMvcPropertiesmvcProperties
:获取和spring.mvc绑定的所有的值的对象ListableBeanFactorybeanFactory
:Spring的beanFactory(容器工厂)HttpMessageConverters
:找到所有的HttpMessageConvertersResourceHandlerRegistrationCustomizer
: 找到资源处理器的自定义器(重点)
ServletRegistrationBean
:给应用注册Servlet,Filter…
c4.配置了message Converters
c5.配置了视图解析器:
c6.配置了资源处理器:
- 1.
在这个资源处理器方法中中设置了所有资源处理的默认规则
,下面对其中的代码进行分析:
1、查看
resourceProperties
中的第1个属性是:isAddMappings,是和静态资源访问相关的
- 1.在资源处理器源码中可以看到先判断
this.resourceProperties.isAddMappings()是否为真
:
- 2.this.resourceProperties的值是从哪里来的呢?? 根据源码可知,是
从这个类中的有参构造中获取到的
- 3.在构造器这里的resourceProperties的值是,
都是从容器中拿到的
2、分析在
isAddMappings()
方法的含义:
- 1.点击
isAddMappings()
,查看isAddMappings()
源码
- 2.在
isAddMappings()
方法中返回了isAddMappings的属性值
- 3.可以看到
isAddMappings属性的
默认值是true:
- 4.
ResourcesProperties
这个类是和spring.resources
绑定在一起的,我在配置文件中设置isAddMappings
值为false:
- 5.我在配置文件配置后,所有的静态资源都被禁用,执行在if判断中的内容后就return了:
3、查看
resourceProperties
中的第二个属性是:Cache,是和配置缓存策略相关的
- 1.分析缓存配置:
- 2.配置缓存配置时间,缓存时间以秒为单位:
4、再继续分析下面的代码:就是判断webjars请求相关的了:
- 1.当请求是webjars/**。就去资源目录META-INF/下去查找资源,且同时设置了资源缓存的时间:
- 2.请求测试设置的缓存时间是否生效:
c7.配置了欢迎页的处理规则:
- 1.
HandlerMapping
:就是处理器映射。在其中保存了每一个Handler能处理哪些请求
@Beanpublic WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),this.mvcProperties.getStaticPathPattern());welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());return welcomePageHandlerMapping;}WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,ApplicationContext applicationContext, Optional<Resource> welcomePage, String staticPathPattern) {if (welcomePage.isPresent() && "/**".equals(staticPathPattern)) {//要用欢迎页功能,必须是/**logger.info("Adding welcome page: " + welcomePage.get());setRootViewName("forward:index.html");}else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {// 调用Controller /indexlogger.info("Adding welcome page template: index");setRootViewName("index");}}
- 2.如下代码截图可以看到要用欢迎页功能,
请求路径必须是/**
,一旦加了前缀就失效了