Spring是一个开源框架,2003年兴起的一个轻量级的Java开发框架,作者:RodJohnson。
Spring是为下解决企业级应用开发的复杂性而创建的,简化开发。
为了降低Java开发的复杂性,Spring采用了以下4种关键策略:
一个javaweb的开发框架,和SpringMVC类似,对比其他javaweb框架的好处,官方说是简化开发,约定大于配置,you can “just run”,能迅速的开发web应用,几行代码开发一个http接口
所有的技术框架的发展似乎都遵循了一条主线规律:从一个复杂应用场景衍生一种规范框架,人们只需要进行各种配置而不需要自己去实现它,这时候强大的配置功能成了优点;发展到一定程度之后,人们根据实际生产应用情况,选取其中实用功能和设计精华,重构出一些轻量级的框架;之后为了提高开发效率,嫌弃原先的各类配置过于麻烦,于是开始提倡“约定大于配置”,进而衍生出一些一站式的解决方案。
Spring Boot的主要优点
开发任何一个Spring Boot项目,都会用到如下的启动类
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
从上面代码可以看出,Annotation定义(@SpringBootApplication)和类定义(SpringApplication.run)最为耀眼,所以要揭开SpringBoot的神秘面纱,我们要从这两位开始就可以了。
springboot所有自动配置都是在启动的时候扫描并加载:springfactories所有的自动配置类都在这里面,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效然后就配置成功!
了解完自动装配的原理后,我们来关注一个细节问题,自动配置类必须在一定的条件下才能生效:
@Conditional派生注解(Spring注解版原生的@Conditional作用)
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;
@ConditionalOnExpression | 当表达式为true的时候,才会实例化一个Bean |
---|---|
@ConditionalOnBean | 当容器中有指定Bean的条件下进行实例化 |
@ConditionalOnMissingBean | 当容器里没有指定Bean的条件下进行实例化 |
@ConditionalOnClass | 当classpath类路径下有指定类的条件下进行实例化 |
@ConditionalOnMissingClass | 当类路径下没有指定类的条件下进行实例化 |
@ConditionalOnWebApplication | 当项目是一个Web项目时进行实例化 |
@ConditionalOnNotWebApplication | 当项目不是一个Web项目时进行实例化 |
@ConditionalOnProperty | 当指定的属性有指定的值时进行实例化 |
@ConditionalOnExpression | 基于SpEL表达式的条件判断 |
@ConditionalOnJava | 当JVM版本为指定的版本范围时触发实例化 |
@ConditionalOnResource | 当类路径下有指定的资源时触发实例化 |
@ConditionalOnJndi | 在JNDI存在的条件下触发实例化 |
@ConditionalOnSingleCandidate | 当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化 |
那么多的自动配置类,必须在一定的条件下才能生效:也就是说,我们加载了这么多的配置类,但不是所有的都生效了。
我们怎么知道哪些自动配置类生效;我们可以通过启用debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;
# 开启springboot的调试类,查看哪些自动配置类生效了,哪些没有生效
debug=true
输出的日志我们可以在这里看下:
YAML是"YAML Ain’t a Markup Language"(YAML不是一种置标语言)的递归缩写。
在开发的这种语言时,YAML的意思其实是:“Yet Another Markup Language”(仍是一种置标语言)
YAML A Markup Language:是一个标记语言
YAML isnot Markup Language:不是一个标记语言
标记语言
以前的配置文件,大多数都是使用xml来配置;比如一个简单的端口配置,我们来对比下yaml和xml
yaml配置:
server:
port: 8080
xml配置:
<server>
<port>8080port>
server>
基本语法:
k:(空格)v
以此来表示一对键值对(空格不能省略);以空格的缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
注意:属性和值的大小写都是十分敏感的。
例子:
# 对空格的要求十分严格
# 注入到我们的配置类中!
# 普通的key-value
name: zxl
# 对象
student:
name: zxl
age: 22
# 行内写法
student: {
name: zxl,age: 22}
# 数组
pets:
- cat
- dog
- pig
pets: [cat,dog,pig]
实体类加@Component注册bean和@ConfigurationProperties(prefox = “在yml文件中的实体类名”)
弹出配置提示,可配置可不配置,配置会出现提示,不配置会爆红但是不影响
导入配置依赖,就不会爆红没交给springboot配置
<dependency>
<groudId>org.springframework.bootgroudId>
<artifactId>spring-boot-configuration-processorartifactId>
dependency>
yaml中的值也可以从properties中用el表达式获取
properties配置文件如果要使用中文,为了避免乱码需要到settings–>FileEncoding中配置UTF-8
-
后面跟着的字母默认是大写的。这就是松散绑定springboot中可以使用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。这里写个注解让name只能支持Email格式
@Component//注册bean
@ConfigurationProperties(prefix = "person")
@Validated//数据校验
public class Person{
//@Value("${person.name}")
@Email(message="邮箱格式错误")
private String name;
@NotNull(message="名字不能为空")
private String userName;
@Max(value=120,message="年龄最大不能查过120")
private int age;
}
@Null | 验证对象是否为null |
---|---|
@NotNull | 验证对象是否不为null,无法查检长度为0的字符串 |
@NotBlank | 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格. |
@NotEmpty | 检查约束元素是否为NULL或者是EMPTY. |
@AssertTrue | 验证Boolean对象是否为true |
---|---|
@AssertFalse | 验证Boolean对象是否为false |
@size(min=,max=) | 验证对象(Array,CollectionMap,string)长度是否在给定的范围之内 |
---|---|
@Length(min=,max=) | Validates that the annotated string is between min and max included. |
@Past | 验证Date和Calendar对象是否在当前时间之前 |
---|---|
@Future | 验证Date和Calendar对象是否在当前时间之后 |
@Pattern | 验证String对象是否符合正则表达式的规则 |
实际上全部都可以用正则表达式实现
springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件
优先级1:项目路径下的config文件夹配置文件
优先级2:项目路径下配置文件
优先级3:资源路径下的config文件夹配置文件
优先级4:资源路径下配置文件
优先级从高到弱
file:./config
file:./
classpath:/config
classpath:/(默认resource目录下)
注意该方式在springboot 2.4版本之后
spring.profiles
替换为spring.config.activate.on-profile
spring.profiles.active
参数,采用spring.config.activate.on-profile
定义的标识名称