SpringBoot笔记
SpringBoot简介
Spring介绍
Spring是一个开源框架,2003 年兴起的一个轻量级的Java 开发框架,作者:Rod Johnson 。
Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。
为了降低Java开发的复杂性,Spring采用了以下4种关键策略:
1、基于POJO的轻量级和最小侵入性编程,所有东西都是bean;
2、通过IOC,依赖注入(DI)和面向接口实现松耦合;
3、基于切面(AOP)和惯例进行声明式编程;
4、通过切面和模版减少样式代码,RedisTemplate,xxxTemplate;
什么是SpringBoot?
SpringBoot是一个javaweb的开发框架,和SpringMVC类似,对比其他javaweb框架的好处,官方说是简化开发,约定大于配置, you can “just run”,能迅速的开发web应用,几行代码开发一个http接口。
随着 Spring 不断的发展,涉及的领域越来越多,项目整合开发需要配合各种各样的文件,慢慢变得不那么易用简单,违背了最初的理念,甚至人称配置地狱。Spring Boot 正是在这样的一个背景下被抽象出来的开发框架,目的为了让大家更容易的使用 Spring 、更容易的集成各种常用的中间件、开源软件;
Spring Boot 基于 Spring 开发,Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说,它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具。Spring Boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。同时它集成了大量常用的第三方库配置(例如 Redis、MongoDB、Jpa、RabbitMQ、Quartz 等等),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用。
简单来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架 。
Spring Boot的主要优点:
- 为所有Spring开发者更快的入门
- 开箱即用,提供各种默认配置来简化项目配置
- 内嵌式容器简化Web项目
- 没有冗余代码生成和XML配置的要求
Spring开发-HelloWord
项目创建
Spring官方提供了非常方便的工具让我们快速构建应用
Spring Initializr:https://start.spring.io/
项目创建方式一:使用Spring Initializr 的 Web页面创建项目
2、填写项目信息
3、点击”Generate Project“按钮生成项目;下载此项目
4、解压项目包,并用IDEA以Maven项目导入,一路下一步即可,直到项目导入完毕。
5、如果是第一次使用,可能速度会比较慢,包比较多、需要耐心等待一切就绪。
项目创建方式二:使用 IDEA 直接创建项目
1、创建一个新项目
2、选择spring initalizr , 可以看到默认就是去官网的快速构建工具那里实现
3、填写项目信息
4、选择初始化的组件(初学勾选 Web 即可)
5、填写项目路径
6、等待项目构建成功
项目结构分析:
通过上面步骤完成了基础项目的创建。就会自动生成以下文件。
1、程序的主启动类
2、一个 application.properties 配置文件
3、一个 测试类
4、一个 pom.xml
更改端口号
在 application.properties文件中加入Server.port=8081
。
更改Banner
如何更改启动时显示的字符拼成的字母,SpringBoot呢?也就是 banner 图案;
只需一步:到项目下的 resources 目录下新建一个banner.txt 即可。
图案可以到:https://www.bootschool.net/ascii 这个网站生成,然后拷贝到文件中即可!
pom.xml
这里我们在引入一些SpringBoot依赖的时候,不需要指定版本,就因为父依赖有这些版本仓库,也就是核心依赖在父工程中。
其中它主要依赖一个父项目spring-boot-starter-parent,主要管理项目的资源过滤及插件。
点进去,发现还有一个父依赖spring-boot-dependencies。这里才是真正管理SpringBoot应用里面所有依赖版本的地方,SpringBoot的版本控制中心;
以后我们导入依赖默认是不需要写版本;但是如果导入的包没有在依赖中管理着就需要手动配置版本了;
启动器 spring-boot-starter
1 | <dependency> |
- 启动器:说白了就是SpringBoot的启动场景
- 比如spring-boot-starter-web,会帮我们自动导入web环境所有的依赖
- springboot会将所有功能场景,都变成一个个的启动器
- 我们要是用什么功能,就需要找到一个个启动器就可以了
主启动类
1 | package com.example.springboot01helloworld; |
@SpringBootConfiguration:SpringBoot的配置
@Configuration: spring配置类 @Component:说明这也是一个spring的组件
1
2
3
4
5
6
7
8
9
- @EnableAutoConfiguration:自动配置
- ```java
@AutoConfigurationPackage:自动配置包
@Import({Registrar.class}):导入了选择器
@Import({AutoConfigurationImportSelector.class}):自动配置选择器
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
//获取所有的配置
获取候选的配置
1
2
3
4
5
6protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
12345META-INF/spring.factories:自动配置的核心文件
SpringBoot所有的自动配置,都在启动类中被扫描并加载:所有的自动配置类都在这里面,但是不一定生效,要判断条件是否成立,只要导入了对应的starter们就有对应的启动器了,有了启动器,我们的自动装配就会生效,然后就配置成功了
- SpringBoot在启动的时候,从类路径下/META-INF/spring.factories获取指定的值
- 将这些自动配置的类导入容器,自动配置类就会生效,帮我们进行自动配置
- 以前我们需要自动配置的东西,现在不需要了
- 整合javaEE,解决方案和自动配置的东西都在Spring-boot-autoconfigure下
- 它会把所有需要导入的组件,以类名的方式返回这些组件,这些组件就会被添加到容器
- 容器中也会存在非常多的XXXAutoConfigure的文件(@Bean),就是这个类给容器导入了这个场景所需要的所有组件并自动配置
SpringApplication
开启了一个服务。
SpringApplication.run:分析该方法主要分两部分,一部分是SpringApplication的实例化,二是run方法的执行;
SpringApplication主要做了以下四件事情:
- 推断应用的类型是普通的项目还是Web项目
- 查找并加载所有可用初始化器 , 设置到initializers属性中
- 找出所有的应用程序监听器,设置到listeners属性中
- 推断并设置main方法的定义类,找到运行的主类
查看构造器:
1 | public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) { |
run方法流程分析
关于SpringBoot,谈谈你的理解:
- 自动装配:如何加载
- run方法:如何启动
全面接管SpringMVC的配置!
yaml
配置文件
SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的
- application.properties
- 语法结构 :key=value
- application.yml
- 语法结构 :key:空格 value
配置文件的作用 :修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;
yaml概述
YAML是 “YAML Ain’t a Markup Language” (YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)
这种语言以数据作为中心,而不是以标记语言为重点!
以前的配置文件,大多数都是使用xml来配置;比如一个简单的端口配置,我们来对比下yaml和xml
传统xml配置:
1 | <server> |
yaml配置:
1 | server: |
yaml基础语法
1 | # k-v键值对 |
说明:语法要求严格!
1、空格不能省略
2、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
3、属性和值的大小写都是十分敏感的。
字面量:普通的值 [ 数字,布尔值,字符串 ]
字面量直接写在后面就可以 , 字符串默认不用加上双引号或者单引号;
1 | k: v |
注意:
“ ” 双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;
比如 :name: “kuang \n shen” 输出 :kuang 换行 shen
‘’ 单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出
比如 :name: ‘kuang \n shen’ 输出 :kuang \n shen
对象、Map(键值对)
1 | #对象、Map格式 |
在下一行来写对象的属性和值得关系,注意缩进;比如:
1 | student: |
行内写法
1 | student: {name: qinjiang,age: 3} |
数组( List、set )
用 - 值表示数组中的一个元素,比如:
1 | pets: |
行内写法
1 | pets: [cat,dog,pig] |
修改SpringBoot的默认端口号
配置文件中添加,端口号的参数,就可以切换端口;
1 | server: |
可以注入到我们的配置类当中
注入配置文件
yaml文件更强大的地方在于,他可以给我们的实体类直接注入匹配值!
1 | <!-- 导入配置文件处理器,配置文件进行绑定就会有提示,需要重启 --> |
yaml注入配置文件
1、在springboot项目中的resources目录下新建一个文件 application.yml
2、编写一个实体类 Dog;
1 | package com.example.springboot02configure.pojo; |
3、编写一个person类
1 | package com.example.springboot02configure.pojo; |
4、 在yaml中写入对象
1 | Person: |
5、 在测试程序中测试
1 | package com.example.springboot02configure; |
加载指定的配置文件
@PropertySource :加载指定的配置文件;
@configurationProperties:默认从全局配置文件中获取值;
1、我们去在resources目录下新建一个person.properties文件
1 | name=kuangshen |
2、然后在我们的代码中指定加载person.properties文件
1 |
|
配置文件占位符
配置文件还可以编写占位符生成随机
1 | Person: |
对比小结
@Value这个使用起来并不友好!我们需要为每个属性单独注解赋值,比较麻烦;我们来看个功能对比图
1、@ConfigurationProperties只需要写一次即可 , @Value则需要每个字段都添加
2、松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下
3、JSR303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性
4、复杂类型封装,yml中可以封装对象 , 使用value就不支持
JSR303检验
1 | 空检查 |
结论:
配置yml和配置properties都可以获取到值 , 强烈推荐 yml;
如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;
如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties,不要犹豫!
多环境切换
profile是Spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境;
多配置文件
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本;
例如:
application-test.properties 代表测试环境配置
application-dev.properties 代表开发环境配置
但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;
我们需要通过一个配置来选择需要激活的环境:
1 | #比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试; |
yaml的多文档块
和properties配置文件中一样,但是使用yml去实现不需要创建多个配置文件,更加方便了 !
1 | server: |
注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的!
配置文件加载位置
外部加载配置文件的方式十分多,我们选择最常用的即可,在开发的资源文件中进行配置!
官方外部配置文件说明参考文档
springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件:
1 | 优先级1:项目路径下的config文件夹配置文件优先级 |
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
SpringBoot会从这四个位置全部加载主配置文件;互补配置;
自动配置原理
配置文件到底能写什么?怎么写?
SpringBoot官方文档中有大量的配置,我们无法全部记住
分析自动配置原理
我们以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;
1 | //表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件; |
一句话总结 :根据当前不同的条件判断,决定这个配置类是否生效!
- 一但这个配置类生效;这个配置类就会给容器中添加各种组件;
- 这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
- 所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;
- 配置文件能配置什么就可以参照某个功能对应的这个属性类
1 | //从配置文件中获取指定的值和bean的属性进行绑定 |
这就是自动装配的原理!
精髓
1、SpringBoot启动会加载大量的自动配置类
2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
xxxxAutoConfigurartion:自动配置类;给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
使用debug=true
可以查看哪些自动配置类生效,哪些没有生效。
MVC配置原理
官网阅读
在进行项目编写前,我们还需要知道一个东西,就是SpringBoot对我们的SpringMVC还做了哪些配置,包括如何扩展,如何定制。
只有把这些都搞清楚了,我们在之后使用才会更加得心应手。途径一:源码分析,途径二:官方文档!
1 | Spring MVC Auto-configuration |
我们来仔细对照,看一下它怎么实现的,它告诉我们SpringBoot已经帮我们自动配置好了SpringMVC,然后自动配置了哪些东西呢?
ViewResolver 视图解析器
自动配置了ViewResolver,就是我们之前学习的SpringMVC的视图解析器;
即根据方法的返回值取得视图对象(View),然后由视图对象决定如何渲染(转发,重定向)。
我们去看看这里的源码:我们找到 WebMvcAutoConfiguration , 然后搜索ContentNegotiatingViewResolver。找到如下方法!
1 |
|
自定义ViewResolver
https://mp.weixin.qq.com/s/9AY48uLjR9bI9TUlulcBNA
转换器和格式化器
修改SpringBoot的默认配置
这么多的自动配置,原理都是一样的,通过这个WebMVC的自动配置原理分析,我们要学会一种学习方式,通过源码探究,得出结论;这个结论一定是属于自己的,而且一通百通。
SpringBoot的底层,大量用到了这些设计细节思想,所以,没事需要多阅读源码!得出结论;
SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(如果用户自己配置@bean),如果有就用用户配置的,如果没有就用自动配置的;
如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和自己默认的组合起来!
扩展使用SpringMVC 官方文档如下:
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 | //应为类型要求为WebMvcConfigurer,所以我们实现其接口 |
确实也跳转过来了!所以说,我们要扩展SpringMVC,官方就推荐我们这么去使用,既保SpringBoot留所有的自动配置,也能用我们扩展的配置!
我们可以去分析一下原理:
1、WebMvcAutoConfiguration 是 SpringMVC的自动配置类,里面有一个类WebMvcAutoConfigurationAdapter
2、这个类上有一个注解,在做其他自动配置时会导入:@Import(EnableWebMvcConfiguration.class)
3、我们点进EnableWebMvcConfiguration这个类看一下,它继承了一个父类:DelegatingWebMvcConfiguration
1 | public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { |
4、我们可以在这个类中去寻找一个我们刚才设置的viewController当做参考,发现它调用了一个
1 | protected void addViewControllers(ViewControllerRegistry registry) { |
5、我们点进去看
1 | public void addViewControllers(ViewControllerRegistry registry) { |
所以得出结论:所有的WebMvcConfiguration都会被作用,不止Spring自己的配置类,我们自己的配置类当然也会被调用;可以在这个类中去寻找一个我们刚才设置的viewController当做参考,发现它调用了一个
@EnableWebMvc 就是导入了一个 DelegatingWebMvcConfiguration 类,从容其中获取所有的webmvcconfig
在SpringBoot中由非常多的xxxConfiguration,会帮助我们进行扩展,只要看见了这个东西我们就要注意了
页面国际化
https://mp.weixin.qq.com/s/e4Jd3xIMF4C4HBzPQfakvg
自定义starter
https://mp.weixin.qq.com/s/2eB2uT088BvzaqRULezdsw
参考文章
SpringBoot笔记