了解SpringBoot
使用SpringBoot首先需要了解什么是Spring,若无基础请先学习Spring、SpinrgMVC
什么是Spring
Spring是一个开源框架,2003 年兴起的一个轻量级的Java 开发框架,作者:Rod Johnson 。
Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。
Spring是如何简化Java开发的
为了降低Java开发的复杂性,Spring采用了以下4种关键策略:
- 基于POJO的轻量级和最小侵入性编程,所有东西都是bean;
- 通过IOC,依赖注入(DI)和面向接口实现松耦合;
- 基于切面(AOP)和惯例进行声明式编程;
- 通过切面和模版减少样式代码,RedisTemplate,xxxTemplate;
什么是SpringBoot?
学过javaweb的同学就知道,开发一个web应用,从最初开始接触Servlet结合Tomcat, 跑出一个Hello Wolrld程序,是要经历特别多的步骤;后来就用了框架Struts,再后来是SpringMVC,到了现在的SpringBoot,过一两年又会有其他web框架出现;你们有经历过框架不断的演进,然后自己开发项目所有的技术也在不断的变化、改造吗?建议都可以去经历一遍;
言归正传,什么是SpringBoot呢,就是一个javaweb的开发框架,和SpringMVC类似,对比其他javaweb框架的好处,官方说是简化开发,约定大于配置, you can “just run”,能迅速的开发web应用,几行代码开发一个http接口。
所有的技术框架的发展似乎都遵循了一条主线规律:从一个复杂应用场景 衍生 一种规范框架,人们只需要进行各种配置而不需要自己去实现它,这时候强大的配置功能成了优点;发展到一定程度之后,人们根据实际生产应用情况,选取其中实用功能和设计精华,重构出一些轻量级的框架;之后为了提高开发效率,嫌弃原先的各类配置过于麻烦,于是开始提倡“约定大于配置”,进而衍生出一些一站式的解决方案。
是的这就是Java企业级应用->J2EE->spring->springboot的过程。
随着 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 Boot 已经当之无愧成为 Java 领域最热门的技术。
SpringBoot的主要优点
- 为所有Spring开发者更快的入门
- 开箱即用,提供各种默认配置来简化项目配置
- 内嵌式容器简化Web项目
- 没有冗余代码生成和XML配置的要求
前言:http://blog.cuicc.com/blog/2015/07/22/microservices/
如何创建一个SpringBoot程序
创建一个SpringBoot程序有两种方式
方式一:
1. 进入Spring的官网选择以下
填写相关内容然后下载解压打包到IDEA即可运行
方式二:
直接通过IDEA创建
点击Next即可创建完成
如何运行第一个Springboot程序
-
首先在主程序的同级目录下,新建一个controller包,一定要在同级目录下,否则识别不到
-
在包中创建一个类
@RestController
@RequestMapping(value = "/hello")
public class hellospringboot {
@GetMapping(value = "/hello")
@ResponseBody
public String hello() {
return "hello SpringBoot";
}
}
3.运行tomcat输入对应url即可访问到内容
自定义banner图案
- 首先在创建resources目录下创建一个叫banner.txt的文件
- 把需要显示的东西粘贴进去重启服务器即可(https://www.bootschool.net/ascii-art)
妙蛙种子哈哈哈哈
SpringBoot的原理初解
自动配置:
pom.xml
-
spring-boot-start-dependencies :核心依赖在父类工程中!
-
在写入或者引用一些SpringBoot依赖的时候,不需要指定版本,就是因为有这些版本仓库
**启动器**
<!-- web场景启动器 start-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<!-- web场景启动器 end-->
- 启动器:说白了就是SpringBoot的启动场景;
- 比如>spring-boot-starter-web,他就会帮我们自动带入web环境所有的依赖!
- springboot会将所有的功能场景,都变成一个个启动器
- 我们要使用什么功能,就只需要找到对应的启动器就可以了 starter
主程序
@SpringBootApplication
public class Springboot01Application {
public static void main(String[] args) {
SpringApplication.run(Springboot01Application.class, args);
}
}
SpringBoot的一些注解
注解 | 作用 |
---|---|
@SpringBootApplication | 标注在某个类上说明这个类是SpringBoot的主配置类 , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用; |
@ComponentScan | 自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中 |
@SpringBootConfiguration | SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类; |
@EnableAutoConfiguration | 开启自动配置功能 |
@AutoConfigurationPackage | 自动配置包 |
@Import({AutoConfigurationImportSelector.class}) | Spring底层注解@import , 给容器中导入一个组件 |
SpringBoot自动装配原理结论:SpringBoot所有自动配置都是在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里面,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功!
- springboot在启动的时候,从类路径下/META-INF/spring.factories获取指定的值;
- 将这些自动配置的类导入容器,自动装配就会生效,帮我进行自动配置;
- 以前我们需要自动配置的东西,现在springboot帮我们做了!;
- 整合JavaEE,解决方案都在spring-boot-autoconfigure:2.3.4.RELEASE.jar这个包下;
- 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器;
- 容器中爷会存在非常多的XXXAutoConfiguration的文件(@Bean),就是这些类给容器中导入了这个场景所需要的所有组件并自动配置,@Configuration,JavaConfig
- 有了配置类,免去了我们手动编写配置文件的工作!
SpringApplication
最初以为就是运行了一个main方法,没想到却开启了一个服务;
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
SpringApplication.run分析
分析该方法主要分两部分,一部分是SpringApplication的实例化,二是run方法的执行;
SpringApplication这个类主要做了以下四件事情:
-
推断应用的类型是普通的项目还是Web项目
-
查找并加载所有可用初始化器 , 设置到initializers属性中
-
找出所有的应用程序监听器,设置到listeners属性中
-
推断并设置main方法的定义类,找到运行的主类
构造器
public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
// ......
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.setInitializers(this.getSpringFactoriesInstances();
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
SpringBoot配置
配置文件
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配置:
<server>
<port>8081<port>
</server>
server:
prot: 8080
yaml基础语法
说明:语法要求严格!
- 空格不能省略
- 以缩进来控制层级关系,只要是左边对齐的一列数据都是同一级层级的(类似于python)。
- 属性和值大小写都是十分敏感的。
#普通的key-value
name: bqyz
#对象
student:
name: bqyz
age: 3
#行内写法
student: {name: bqyz,age: 10}
#数组
lista:
- a
- b
- c
list: [a,b,c]
当application.properties和application.yaml同时存在时@ConfigurationProperties(prefix= “person”)无法使用,因为SpringBoot不知道你加载的是那个配置文件,默认加载yaml,这时候就需要使用@PropertuSource(value = “classpath:bqyz.properties”),
@PropertuSource(value = “classpath:bqyz.properties”)加载指定路径的配置文件
然后在需要赋值的属性上面添加@Value(“name”)注解
1、@ConfigurationProperties只需要写一次即可 , @Value则需要每个字段都添加
2、松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下
3、JSR303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性
4、复杂类型封装,yml中可以封装对象 , 使用value就不支持
结论:官方推荐使用application.yaml,也就是@ConfigurationProperties自动配置,因为它更简单,代码更简便,功能更灵活。
JSR-303
JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。
注解 | 作用 |
---|---|
@Null | 限制只能为null |
@NotNull | 限制必须不为null |
@NotEmpty | 只作用于字符串类型,字符串不为空,并且长度不为0 |
@NotBlank | 只作用于字符串类型,字符串不为空,并且trim()后不为空串 |
@AssertFalse | 限制必须为false |
@DecimalMax | 限制必须为true |
@DecimalMax(value) | 限制必须为一个不大于指定值的数字 |
@DecimalMin(value) | 限制必须为一个不小于指定值的数字 |
@Digits(integer,fraction) | 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction |
@Future | 限制必须是一个将来的日期 |
@Past | 验证注解的元素值(日期类型)比当前时间早 |
@Max(value) | 限制必须为一个不大于指定值的数字 |
@Min(value) | 限制必须为一个不小于指定值的数字 |
@Pattern(value) | 限制必须符合指定的正则表达式 |
@Size(max,min) | 限制字符长度必须在min到max之间 |
验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 | |
@Length(min=, max=) | 验证字符串长度介于 min 和 max 之间 |
//使用实例
@NotNull(message="名字不能为空")
private String userName;
@Max(value=120,message="年龄最大不能查过120")
private int age;
@Email(message="邮箱格式错误")
private String email;
空检查
@Null 验证对象是否为null
@NotNull 验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty 检查约束元素是否为NULL或者是EMPTY.
Booelan检查
@AssertTrue 验证 Boolean 对象是否为 true
@AssertFalse 验证 Boolean 对象是否为 false
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
@Length(min=, max=) string is between min and max included.
日期检查
@Past 验证 Date 和 Calendar 对象是否在当前时间之前
@Future 验证 Date 和 Calendar 对象是否在当前时间之后
@Pattern 验证 String 对象是否符合正则表达式的规则
多配置文件环境切换
application.yaml是可以写在四个地方,SpringBoot都会去扫描,但是它有优先级。
- file:./config/ 当前工程下的config文件夹里的application.yaml如果四个都存在首先启用当前文件下的application,优先级第一
- file:./ 当前工程下的application.yaml 优先级第二
- classpath:/config/ 资源路径下的config文件夹下的application.yaml ,优先级第三
- classpath:/ 资源路径下的application.yaml ,优先级第四
同一路径下可以有多个application-xx.yaml,其中xx代表着开发环境,比如application-test.yaml测试环境 ,application-dev.yaml开发环境,默认会读取application.yaml,我们可以通过spring.profiles.active=xx 进行激活切换到选择的环境
#比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试;
#我们启动SpringBoot,就可以看到已经切换到dev下的配置了;
#application.yaml
spring:
profiles:
active: dev
#application-dev.yaml
server:
port: 8081
这样我们就激活了application-dev.yaml的配置,SpringBoot就会默认使用这个配置
注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的!
如果你觉得写多个配置文件太麻烦的话,没关系SpringBoot还提供了一个文件写多文档功能!
例子:
#设置服务器启动端口号,Tomcat默认8080
#server.port=8081
#选择启动名为test的环境
spring:
profiles:
active: test
--- #三条杠进行分割,说明下面的代码属于一个新的环境
server:
port: 8001
spring:
#给当前代码块命名为dev,等价于application-dev.yaml
#这样我们就不用创建多个文件了,很方便 ,通过 ---三条杠进行分割
profiles: dev
---
server:
port: 8002
spring:
profiles: test