本学习笔记是学习尚硅谷的SpringBoot教程过程中一些问题和关键知识点的记录。
版本:
JDK1.8
SpringBoot:1.5.9
Maven:3.3.9
Idea:2020.01
一、SpringBoot应用的基本组件构成
- SpringBoot启动器:程序的主启动类,启动时会自动的把应用打包部署到内置的Tomcat服务器上
- Controller:处理请求
- Service:为Controller层的处理提供服务
- Dao:与数据库进行映射
- Entity:实体类
一个SpringBoot应用的结构与传统SSM的结构几乎完全一致,但是内部简化了开发中部署、配置的操作,从而可以更快速的创建一个应用。
二、SpringBoot特性
- 自动配置:SpringBoot最重要的特性就是自动配置,SpringBoot定义了很多配置类,配置类中设定了每个配置的默认值,默认就使用这些默认配置,当有个别需要修改时再从配置文件中覆盖修改需要修改的配置。
- 快速启动:SpringBoot程序可以打成一个Jar包。在服务器上直接用java -jar 直接运行。因为打包时携带了嵌入式的tomcat服务器包,在lib文件夹中有tomcat的jar包。
- 启动器:Springboot有很多不同的启动器,将所有的功能场景抽取出来,做成一个个starter,需要用时,只需要在项目中导入对应场景的启动器,springboot就会帮我们导入该场景所需要的依赖集合。而版本则由版本仲裁统一管理。
三、SpringBoot依赖与配置解析
1.pom文件解析
spring-boot-starter-parent
:SpringBoot 的版本仲裁中心(父项目),里面定义了常用依赖的默认版本。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/>
</parent>
spring-boot-starter-web
: SpringBoot的web开发启动器,包含了tomcat
springMVC
jeckson
等等web模块所需要的依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.启动类解析
@SpringBootApplication
– 标注一个类是主启动类
@SpringBootConfiguration
– 表示是一个SpringBoot的配置类(里面包含Spring的)
@Configuration
– Spring中标识配置类的注解
@EnableAutoConfiguration
– 开启自动配置
@AutoConfigurationPackage
– 自动配置包注解
@Import(AutoConfigurationPackages.Regisrtar.class)
– 导入自动配置包中的一个内部类
registerBeanDefinitions()
– 自动扫描主启动类所在包及其子包下的注解,并将他们加载到Spring容器的方法
@import
– 给容器中导入组件
@Import({AutoConfigurationImportSelector.class})
– 给容器中导入组件
AutoConfigurationImportSelector.class
– 组件选择器。选择器会返回要导入组件的一个全类名String数组。在这里导入的组件主要是一些自动配置类、一共96个包含常用功能各自的自动配置类(如AOP、MQ、NOSQL数据库等等)。
组件选择器:
调用链:AutoConfigurationImportSelector
—>selectImports
—>getCandidateConfigurations
–>SpringFactoriesLoader.loadFactoryNames();
原理:通过SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);
方法,从SpringBoot包下的META-INF/spring.factories
文件中获取对应的值(96个类名集合)。拿到类名集合后通过反射获取到类的实例对象,加载到容器中。实现了自动配置。自动配置类中一般通过@Bean的方式来往容器中添加配置,只不过用类的方式写好了。J2EE的整体整合解决方案相关的自动配置都在spring-boot-autoconfigure-1.5.9.jar包中,里面有各个功能各自的配置类!
@RestController
– 相当于@Controller + @ResponseBody
声明该Controller向浏览器返回json数据
3.目录结构解析
3.1 resource文件夹
static文件夹:保存所有静态资源(JS、CSS、images)
templates文件夹:保存所有的模板页面(SpringBoot默认jar包使用嵌入式的Tomcat,默认不支持JSP,可以使用freemarker模板引擎)
4.配置文件解析
SpringBoot的全局配置文件:
application.properties
或 application.yml
作用:用于修改默认配置!
4.1 语法规范
YAML
yml:YAML
语法格式、缩进严格,大小写敏感,以数据为中心,用缩进展示层级基本语法:
k:(空格)v
表示一对键值对(空格必须有)
以空格的缩进来表示层级关系;只要是左对齐的一列数据,都是同一个层级的。值的写法:
字面量(数字、字符串、布尔):k: v
(字面量直接写)
字符串默认不用加单引号或者双引号
如果加的话:
双引号不会转义特殊字符,特殊字符(比如\n)会是本身想表达的意思
单引号会转义特殊字符,特殊字符只是一个普通的字符串对象、Map(属性和值)(键值对): 正常写法: k: v 在下一行来写对象和属性的关系;注意缩进 行内写法:
friends:{lastName: zhangsan,age: 18} 注意空格 数组(List、set): 用 -
来表示数组中的一个元素 正常写法: list:
- car
- dog -(空格)值 行内写法: list: [cat,dog,pig]yaml中写上述变量的目的是为了修改配置类的值,由于SpringBoot底层使用配置类来进行默认配置,要修改默认配置,就要通过在配置文件中自定义对应属性的属性值,然后和配置类进行绑定,这样自定义配置的值就可以传到配置类中去了。
绑定通过在配置类添加注解 @Component 表示此类为Spring容器中的组件,可以使用容器的方法
@ConfigurationProperties(prefix = “配置文件中的根标签名,用于找到和当前类所匹配的配置文件内容”)
告诉Springboot将本类中的所有属性和配置文件中的相关配置进行绑定!通过prefix来寻址。可以导入配置文件处理器,就可以有提示了。
写法:last-name 等效于 lastName
properties
person.age=18
person.maps.k1=v1
person.maps.k2=v2
person.dog.name=kele
properties文件需要修改文件编码,默认是UTF-8,需要设置 在运行时把中文转为ACLL码。
配置文件占位符
在配置文件中可以动态的指定配置项的值:
1.随机数:
$ {random.uuid}
$ {random.int}、
2.可以使用之前配置的值,如果配置属性没有声明,就需要
$ {配置属性:默认值}+字符串 来声明默认值
4.2 注解@value和@ConfigurationProperties
作用:在变量上使用,获取配置文件中的信息
操作对比 | @Value | @ConfigurationProperties |
---|---|---|
绑定方式 | 单独绑定 | 批量绑定 |
松散绑定(用-或_来对应大写) | ❌ | ✔ |
spEL | ✔ | ❌ |
注入时校验(在类上加@Validated,在要注入的值上加类似@Email的注解) | ❌ | ✔ |
复杂类型的数据注入(对象、map) | ❌ | ✔ |
两个注解的使用场景:
@Value
:适用于某个业务逻辑中获取一下配置文件的某项值
@ConfigurationProperties
:专门编写了一个JavaBean来和配置文件进行映射
4.3 注解@PropertiesSource和@ImportResource
两个注解的使用场景:
@PropertiesSource
:用于给实体配置类指定引入哪儿个.properties或.yml
文件。例:@PropertiesSource(value={"classpath:person.properties"})
读取类路径下的名为person.properties的配置文件
@ImportResource
:给Spring容器导入xml文件,让Spring来管理xml中的Bean对象等。
4.4 SpringBoot给容器中添加组件的方式
不编写配置文件,推荐使用全注解的方式。
- 编写配置类,类上加注解
@Configuration
表明这是一个配置类,用来代替Spring配置文件。 - 编写配置方法,在方法上加
@Bean
注解。会将方法的返回值添加到容器中,id默认使用方法名来作为id。
4.5 多版本配置文件
配置文件可以分为多个场景,如生产环境、测试环境、开发环境分别有不同的配置。
当主配置文件类型是properties文件时:
可以再创建名称格式为:application-{profile}.properties
的配置文件
例如:application-dev.properties 开发版本的配置文件。
在主配置文件application.properties中可以设置属性:soring.profile.active=dev
当主配置文件是yml时:
在文件中可以通过 三个短横线 来划分语句块 (- - -)
其中,每个语句块通过spring:profiles:dev
来规定各自的名称标识。
在最上面的语句块中可以通过配置:spring:profiles:active:dev
来决定哪儿个哪儿个语句块中的配置文件生效。
命令行的方式激活指定的profile:
-- spring.proties.active=dev
虚拟机参数 VM options:-Dspring.profiles.active=dev
4.6 SpringBoot配置文件加载顺序
在不使用配置中心时,应用内配置文件可能在不同的文件夹存放,默认的加载顺序如下:
应用内:
- file(当前项目文件根目录):./config/
- file:./
- classpath(类路径):/config/
- classpath:/
全局:
- 命令行参数—运行时指定的配置项(可以是某一个具体的配置)可以指定多个,用空格分隔
- 虚拟机或者操作系统环境变量
- jar包外的带profile的配置文件
- jar包内的带profile的配置文件
- jar包外的不带profile的配置文件
- jar包内的不带profile的配置文件
- @Configuration注解类上的@PropertySource
- 通过SpringApplication.setDefaultPproperties指定的默认属性
也可以通过spring.config.location 来改变默认配置
项目打包后,可以使用命令行参数的方式,启动项目时显式指定配置文件位置:
java -jar xxx.jar --spring.config.location=配置文件位置
这样指定的是最高优先级的配置,如果在运行时需要修改少量配置文件,而项目已经打好包了,可以使用这种方法,重写少量的配置文件,同时没有被重写的配置文件也不会收到影响。
4.7 SpringBoot自动配置原理
在启动类解析时提到的选择器AutoConfigurationImportSelector.class
有一个selectImports()
方法,这个方法返回的是一个元素为自动配置类名的List。
这个List通过loadFactoryNameas()
方法,从META-INF/spring.factories
文件中获取要给容器中加载的类的全类名。组装成一个List<String>返回。
拿到类名之后,通过Java的反射机制,就可以访问到该类的内容。
自动配置类都是不同功能的配置类(xxxAutoConfiguration类)
以HttpEncodingAutoConfiguration
为例解析注解:
@Configuration
— 表示这是一个配置类,也可以给容器中添加组件@EnableConfigurationProperties(HttpEncodingProperties.class)
— 启动指定类的@ConfigurationProperties(prefix = xxx)
注解,用来从配置文件中获取指定前缀的值和类的属性进行绑定,并向容器中添加组件。每个配置对应一个属性。@Conditionnal
:@ConditionnalOnWebApplication
— 判断当前应用是否是Web应用。@ConditionalOnClass(CharacterEncodingFilter.class)
—判断当前项目是否有CharacterEncodingFilter这个类@ConditionalOnProperties(profix = "spring.http.encoding" , value="enabled" , matchIfMissing = true)
—判断配置文件中是否存在配置: (spring.http.encoding.enabled)
matchIfMissing:如果不存在,判断也成立。
一旦配置类生效,验证通过后就会通过方法上的@Bean注解来给容器中添加组件(自动配置类)。
组件的参数是从properties类中获取的,而且因为前面有绑定自动配置类和配置文件的关系,所以配置文件中可以配置的属性和自动配置类中所定义的属性一一对应。
小结:
- 每一个xxxAutoConfiguration类对应一个的xxxProperties.class
- SpringBoot启动会加载大量的自动配置类。自动配置类上有用于判断的注解,如果符合条件,配置类就会通过@Bean注解来注入到容器中。
- 配置类注入到容器时,会判断properties中是否重写了这些属性,如果重写了就使用重写的值,没有就使用默认值。
PS:查看有哪儿些配置类生效了
主配置中配置:debug=true 让控制台打印自动配置报告,这样就可以看到哪儿些配置类生效。
Positive matches:生效的配置类,启用 的自动配置类
Negative matches:没启用,没匹配成功的自动配置类
4.8 静态文件相关配置
/**
访问当前项目,如果没人处理,默认去以下路径寻找:
classpath: /META-INF/resources/
classpath: /resources/
classpath: /static/
classpath: /public/
/ (当前项目的根路径 )
(resources就是classpath,resources就是类路径的根目录!)
webjars/**
去 classpath:/META-INF/resources/webjars/
目录下找资源
webjars:以jar包的方式引入资源,比如配置maven依赖下载的jar包也属于webjar的一种
index.html
静态文件夹下的所有index.html页面,默认被"/**" 映射。
例如:localhost:8080/ 就是去寻找欢迎页。
**/favicon.ico
浏览器页签图标。默认在静态文件夹下找。
修改静态文件夹位置
//多个文件夹用逗号分隔
spring.resources.static-locations=/hello,/classpath:/xxx/
(ResourceProperties.java所有有关静态资源的相关配置类)
四、快速创建应用
使用初始化器快速创建一个SpringBoot应用: 使用Spring Initalizr
1.项目基本信息–包名、jdk版本
2.选择模块,选择需要用的模块(web、SQL、NOSQL、分布式等等)
3.动态生成项目(联网)动态生成的项目中,主程序已经有了,只需要编写自己的业务逻辑。