SpringBoot
本文最后更新于 2023-08-16,文章内容可能已经过时,请注意内容的辨别。
SpringBoot
简介
使用 Spring Boot 可以很容易地创建出能直接运行的独立的、生产级别的基于 Spring 的应用。我们对 Spring 平台和第三方类库有自己的考虑,因此您可以从最基本的开始。大多数 Spring Boot 应用只需要很少的 Spring 配置。您可以使用 Spring Boot 来创建一个可以使用 java -jar
命令来运行或者基于传统的 war 包部署的应用程序。
目标
为所有 Spring Boot 开发提供一个更快、更全面的入门体验。
坚持自我虽好,但当需求出现偏离,您需要能迅速摆脱出来。
提供大量非功能性特性相关项目(例如:内嵌服务器、安全、指标、健康检查、外部配置)。
绝对没有代码生成,也不要求 XML 配置。
关键字
选取功能精华
丢弃繁琐配置
约定大于配置(不符合约定的部分,在没有规定配置的地方,采用默认配置)
一站式解决方案
集成第三方库
开箱即用
排错大于使用
简化web项目
运用
大量运用在前后端分离项目与微服务概念项目当中
idea搭建springboot
create New Project==》左边Spring Initializr 》next=》输入组名和Aritifact language java packaging jar java version 8===》next ===>developer Tools SpringBoot devTools、 web springweb >next >finish
项目出来 删除 .mvn、.gitgonre、help.md、mvnw、mvnw.cmd文件
@SpringBootApplication
spring组件
注解的类是我们程序的主入口(不能删不能改)
application.properties
或者是yml 是springboot的配置文件
@SpringBootTest
单元测试
pom文件分析
parent ===》有一个父项目 管理版本
都是spring-boot-starter开头的
-web 集成了tomcat(默认嵌入式容器)、dispatcherServlet、xml。。。
-test 单元测试
执行
双击maven 的package 打包jar包
执行jar包就是java -jar
resources文件夹
静态页面的return默认是跳转到/static/目录下,当在pom.xml中引入了thymeleaf组件,动态跳转会覆盖默认的静态跳转,默认就会跳转到/templates/下 ,一般不用删了
banner
网站copyhttps://www.bootschool.net/ascii-art/search
resources下新建banner.txt
结束!
自动配置
pom
核心依赖在父工程中
启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-xxx</artifactId>
</dependency>
启动器就是springboot应用场景,想用什么样的功能就找什么样的启动器(starter)
常见的的启动器
1、spring-boot-starter Spring Boot核心starter,包含自动配置、日志、yal配置文件支持 2、spring-boot-starter-actuator 准生产特性、用于监控和管理应用 3、spring-boot-starter-remote-shell 提供基于ssh协议的监控和管理 4、spring-boot-starter-amqp 使用spring-rabbitlai zhichi AMQP 5、spring-boot-starter-aop 使用spring-aop和AspectJ支持面向切面编程 6、spring-boot-starter-batch 对Spring Batch的支持 7、spring-boot-starter-cache 对Spring Cache的抽象支持 8、spring-boot-starter-cloud-connectors 对云平台(Cloud Foundry、Heroku)提供的服务提供简化的连接方式 9、spring-boot-starter-data-elasticsearch 通过spring-data-elasticsearch对Elasticsearch支持 10、spring-boot-starter-data-gemfire 通过spring-data-gemfire对分布式存储GemFire的支持 11、spring-boot-starter-data-jpa 对JPA的支持,包含spring-data-jpa、spring-orm和hibernate 12、spring-boot-starter-mongodb 通过spring-data-mongodb,对mongodb的支持 13、spring-boot-starter-rest 通过spring-data-rest-webmvc将Spring Data repository暴露为REST形式服务 14、spring-boot-starter-solr 通过spring-data-solr对Apache Solr数据检索的支持 15、spring-boot-starter-freemarker 对Freemarker模板引擎的支持 16、spring-boot-starter-groovy-templates 通过spring-hateoas对基于HATEOAS的REST形式网络服务支持 17、spring-boot-starter-hornetq 通过HornetQ对JMS的支持 18、spring-boot-starter-integration 对系统集成框架spring-integration支持 19、spring-boot-starter-jdbc 对JDBC数据库的支持 20、spring-boot-starter-jersey 对Jersery REST形式网络服务支持 21、spring-boot-starter-jta-atomikos 通过Atomikos对分布式事务的支持 22、spring-boot-starter-mail 对javax.mail的支持 23、spring-boot-starter-mobile 对spring-mobile的支持 24、spring-boot-starter-mustache 对Mustache模板引擎的支持 25、spring-boot-starter-redis 对Redis的支持,包含spring-redis 26、spring-boot-starter-security 对spring-security的支持 27、spring-boot-starter-social-facebook 对Facebook支持 28、spring-boot-starter-social-linkedin 对linkedin支持 29、spring-boot-starter-social-twitter 对Twitter支持 30、spring-boot-starter-test 对常用测试框架JUnit、Hamcrest和Mockito的支持,包含spring-test模块 31、spring-boot-starter-thymeleaf 对Thymeleaf模板引擎的支持,包含于Spring整合的配置 32、spring-boot-starter-velocity 对Velocity模板引擎的支持 33、spring-boot-starter-web 对Web项目开发支持,包含Tomcat和Spring MVC 34、spring-boot-starter-Tomcat Spring Boot默认Servlet容器 35、spring-boot-starter-Jetty 使用Jetty作为Servlet容器 36、spring-boot-starter-undertow 使用Undertow作为Servlet容器 37、spring-boot-starter-logging Spring Boot默认日志框架logback 38、spring-boot-starter-log4j 支持使用Log4J日志框架 39、spring-boot-starter-websocket 对websocket的支持 40、spring-boot-starter-ws 对Spring Web Service支持
相关注解理解
进入@SpringBootApplication你能看到几个注解
@SpringBootConfiguration
springboot的相关配置
@Configuration(spring中的,代表是个spring配置类)
@EnableAutoConfiguration
自动配置
@AutoConfigurationPackage(自动配置包)
AutoConfigurationPackage注解的作用是将 添加该注解的类所在的package 作为 自动配置package 进行管理。
可以通过 AutoConfigurationPackages 工具类获取自动配置package列表。当通过注解@SpringBootApplication标注启动类时,已经为启动类添加了@AutoConfigurationPackage注解。路径为 @SpringBootApplication -> @EnableAutoConfiguration -> @AutoConfigurationPackage。也就是说当SpringBoot应用启动时默认会将启动类所在的package作为自动配置的package。
@Import({Registrar.class})(注册器)
Registrar.class作用
实现这个接口的类可以在使用@Configuration的地方引入,然后实现动态的bean注入到spring容器,这个是在在@Bean注解定义bean 后动态的注入bean。
@Import({AutoConfigurationImportSelector.class})(选择器)
将AutoConfigurationImportSelector这个类导入到spring容器中,AutoConfigurationImportSelector可以帮助springboot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器
AutoConfigurationImportSelector的selectImports()的 getAutoConfigurationEntry找this.getCandidateConfigurations 找SpringFactoriesLoader.loadFactoryNames找loadSpringFactories找classLoader.getResources("META-INF/spring.factories");就看到了所有自动配置的类
总结
1.@AutoConfigurationPackage将添加该注解的类所在的package 作为 自动配置package 进行管理
2.@Import({Registrar.class})实现动态的bean注入到spring容器,这个是在在@Bean注解定义bean 后动态的注入bean。
3.@Import({AutoConfigurationImportSelector.class})将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器最好带上一句AutoConfigurationImportSelector会找到META-INF/spring.factories文件并加载,这个文件里面里面有所有的配置类
springboot配置
https://docs.spring.io/spring-boot/docs/2.1.16.RELEASE/reference/htmlsingle/ Part X. Appendices 下,
去看看都在这,具体应用具体再说
yml(官方推荐配置文件)
yml与yaml区别
除了后缀不一样,其他没区别
简介
YAML (YAML Ain't a Markup Language)YAML不是一种标记语言,通常以.yml为后缀的文件,是一种直观的能够被电脑识别的数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,一种专门用来写配置文件的语言
特点
这种语言以数据作为中心,而不是以标记语言为重点
优点
YAML易于人们阅读。
YAML数据在编程语言之间是可移植的。
YAML匹配敏捷语言的本机数据结构。
YAML具有一致的模型来支持通用工具。
YAML支持单程处理。
YAML具有表现力和可扩展性。
YAML易于实现和使用。
约定
k: v 表示键值对关系,冒号后面必须有一个空格
使用空格的缩进表示层级关系,空格数目不重要,只要是左对齐的一列数据,都是同一个层级的
大小写敏感
缩进时不允许使用Tab键,只允许使用空格。
松散表示,java中对于驼峰命名法,可用原名或使用-代替驼峰,如java中的lastName属性,在yml中使用lastName或 last-name都可正确映射。
尽量不要写同名参数
表示各种类型(注意加空格!!!!!!!!! 注意缩进 !!!!!!!不缩进认为是一层)
1.普通值(字面量)
name: xiaohuang
2.日期
date: 2020/01/01
3.对象(属性和值)、Map(键值对)
people:
name: shuaige
age: 28
people: {name:shuaige,age: 28}
4.数组、list、set
pets:
- dog
- pig
- cat
pets: [dog,pig,cat]
5.复杂的
peoples:
- name: zhangsan
age: 22
- name: lisi
age: 20
- {name: wangwu,age: 18}
5.文档块(每个块用----隔开)
server:
port: 8081
spring:
profiles:
active: prod #激活对应的文档块
---
server:
port: 8083
spring:
profiles: dev #指定属于哪个环境
---
server:
port: 8084
spring:
profiles: prod #指定属于哪个环境
配置类赋值
stu:
name: 张三
map:
key: value
list:
- a
- b
- c
date: 2021/08/09
teacher:
tname: 李四
age: 18
package com.example.spboot.entity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
@ConfigurationProperties(prefix = "stu")
public class Student {
private String name;
private Map<String,String> map;
private List<String> list;
private Date date;
private Teacher teacher;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Student(String name, Map<String, String> map, List<String> list, Date date, Teacher teacher) {
this.name = name;
this.map = map;
this.list = list;
this.date = date;
this.teacher = teacher;
}
public Student() {
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", map=" + map +
", list=" + list +
", date=" + date +
", teacher=" + teacher +
'}';
}
}
package com.example.spboot.entity;
public class Teacher {
private String name;
private int age;
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
public Teacher() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.example.spboot;
import com.example.spboot.entity.Student;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpbootApplicationTests {
@Autowired
Student student;
@Test
void contextLoads() {
System.out.println(student);
}
}
或者
package com.example.spboot.entity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
@PropertySource("classpath:application.yml")
public class Student {
@Value("${name}")
private String name;
private Map<String,String> map;
private List<String> list;
private Date date;
private Teacher teacher;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Student(String name, Map<String, String> map, List<String> list, Date date, Teacher teacher) {
this.name = name;
this.map = map;
this.list = list;
this.date = date;
this.teacher = teacher;
}
public Student() {
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", map=" + map +
", list=" + list +
", date=" + date +
", teacher=" + teacher +
'}';
}
}
或者直接value直接写值但是不推荐后面两种
简单说下springEl表达式
Spring3中引入了Spring表达式语言—SpringEL,SpEL是一种强大,简洁的装配Bean的方式,他可以通过运行期间执行的表达式将值装配到我们的属性或构造函数当中,更可以调用JDK中提供的静态常量,获取外部Properties文件中的的配置
类似于之前学的el表达式但是又有所不同,并且idea目前不会主动检查报错,排查起来比较难,所以初学者目前不推荐些这种方式。
配置文件的位置
根目录的config文件夹下>项目根目录下>resources下的config文件夹下>项目resources的目录下
多环境下的配置
pro、prd环境:生产环境,面向外部用户的环境,连接上互联网即可访问的正式环境。
pre环境:灰度环境,外部用户可以访问,但是服务器配置相对低,其它和生产一样。
test环境:测试环境,外部用户无法访问,专门给测试人员使用的,版本相对稳定。
dev环境:开发环境,外部用户无法访问,开发人员使用,版本变动很大。
多文件比如allpication-test.properties、allpication-prd.properties 里面都有相关的配置如何做到切换呢 再建一个allpication.properties 里面写spring.profiles.active=dev
2.yml
server:
port: 8080 #这是默认的 没写下面的就是8080 写了下面的就是dev的
spring:
profiles:
active: dev
---
server:
port: 8082
spring:
profiles:test
---
server:
port: 8083
spring:
profiles:dev
#Spring Boot 2.4为了提升对Kubernetes的支持而作的修改
server:
port: 8080 #这是默认的 没写下面的就是8080 写了下面的就是dev的
spring:
profiles:
active: test
---
server:
port: 8082
spring:
config:
activate:
on-profile: test
---
server:
port: 8083
spring:
config:
activate:
on-profile: dev
#Spring Boot 2.4为了提升对Kubernetes k8s的支持而作的修改
JSR303
jSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation。
一般在controller中用于接收数据校验
如何使用?
1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2.创建返回类(当然了,这里仅限于加了@restController的controller)
package com.example.spboot.until;
import java.util.Map;
public class Result {
private boolean success; /*操作成功标志*/
private String result; /*操作结果*/
private String info; /*操作结果提示信息*/
private int status; /*操作结果状态码*/
private Map<String,Object> data; /*操作结果数据*/
public Result() {
}
public Result(boolean success, String info, int status, Map<String, Object> data) {
this.success = success;
this.result = info;
this.info = info;
this.status = status;
this.data = data;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public Map<String, Object> getData() {
return data;
}
public void setData(Map<String, Object> data) {
this.data = data;
}
public static Result ok() {
return ok("操作成功");
}
/*简洁方法,404*/
public Result error404(String info) {
this.setStatus(404);
this.setSuccess(false);
this.setInfo(info);
this.setResult(info);
return this;
}
public Result error400(String info) {
return error400(info,data);
}
public Result error400(String info,Map<String,Object> data) {
this.setStatus(400);
this.setSuccess(false);
this.setInfo(info);
this.setResult(info);
this.data = data;
return this;
}
/*简洁方法,操作成功,200,有返回值*/
public static Result ok(Map<String, Object> data) {
return new Result(true,"操作成功",200,data);
}
/*简洁方法,操作成功,200,无返回值,有提示信息*/
public static Result ok(String info) {
return new Result(true,info,200,null);
}
public static Result error(String info) {
return new Result().error400(info);
}
}
3.实体类加注释 @Null 对象必须为null @NotNull 对象必须不为null,无法检查长度为0的字符串 @NotBlank 字符串必须不为Null,且去掉前后空格长度必须大于0 @AssertTrue 对象必须为true @AssertFalse 对象必须为false @Max(Value) 必须为数字,且小于或等于Value @Min(Value) 必须为数字,且大于或等于Value @DecimalMax(Value) 必须为数字( BigDecimal ),且小于或等于Value。小数存在精度 @DecimalMin(Value) 必须为数字( BigDecimal ),且大于或等于Value。小数存在精度 @Digits(integer,fraction) 必须为数字( BigDecimal ),integer整数精度,fraction小数精度 @Size(min,max) 对象(Array、Collection、Map、String)长度必须在给定范围 @Email 字符串必须是合法邮件地址 @Past Date和Calendar对象必须在当前时间之前 @Future Date和Calendar对象必须在当前时间之后 @Pattern(regexp=“正则”) String对象必须符合正则表达式
package com.example.spboot.entity;
import org.springframework.beans.factory.annotation.Value;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.Null;
public class Dog {
@Null(message = "name必须不为空")
private String name;
@Null(message = "age必须不为空")
@Max(value =150 ,message = "age最大为150")
@Min(value =0 ,message = "age最小为1")
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public Dog() {
}
}
3.Controller
package com.example.spboot.Controller;
import com.example.spboot.entity.Dog;
import com.example.spboot.until.Result;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
@RestController
public class TestController {
@RequestMapping( value = "/hello")
public Result hello(@RequestBody @Valid Dog dog, BindingResult result){
StringBuffer info=new StringBuffer();
if(result.hasErrors()){
List<FieldError> fieldErrors = result.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
info.append(fieldError.getDefaultMessage());
}
return Result.error(info.toString());
}else{
return Result.ok();
}
}
}
整合mybatis
新建項目
勾选
developer Tools === SpringBoot devTools
developer Tools===lombok
web === springweb
sql==mabatis framework 、mysql Driver
建包
controller
mapper
pojo
until
service
resource下也建mapper(看情况)
添加数据源Druid
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
配置文件
server:
port: 8080
spring:
profiles:
active: dev
---
server:
port: 8082
spring:
profiles:test
---
server:
port: 8083
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/kj08?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT
username: root
password: 9320
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
min-idle: 5
max-active: 20
#配置获取连接等待超时的时间
max-wait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: mapper/*.xml
注意点
mapper接口上加@mapper和@Repository(第二个不加项目报错但是能运行)
或者你在启动类写@mapperScan()(不推荐)
idea自定义mapper配置文件
setting==》file and code templates 》+ 》mybatisMapper xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="">
</mapper>
apply
ok
Lombok(不情愿的讲一下)
idea装lombok插件
setting 》plugins》输入lombok install 重启项目
人话:专门搞实体类的和日志
package com.example.spboot.entity;
import lombok.*;
import java.sql.Date;
@Data
public class Student {
private long id;
private long studentNo;
private String loginPwd;
private String studentName;
private long sex;
private String phone;
private String address;
private Date bornDate;
private String email;
private String identityCard;
private long classId;
private String picPath;
}
相关注解
1. @Getter/@Setter
自动产生 getter/setter
2. @ToString
自动重写 toString()
方法,会印出所有变量
3. @EqualsAndHashCode
自动生成 equals(Object other)
和 hashcode()
方法,包括所有非静态变量和非 transient 的变量
4.@NoArgsConstructor
生成一个没有参数的构造器
5.@AllArgsConstructor
生成一个包含所有参数的构造器
6.@Data
整合包,只要加了 @Data 这个注解,等于同时加了以下注解
@Getter/@Setter
@ToString
@EqualsAndHashCode
@RequiredArgsConstructor
7.@Builder
@Builder(toBuilder = true)
Blog.builder().blogid().comment().blogid()
blog.toBuilder().logicDel().comment().blogid()
构造者模式 链式操作
8.@Accessors
@Accessors(chain = true)
blog.setComment().setBlogid().setTitle().getComment()
链式操作
区别 7 是造对象 8不造对象 调用方式也有相关问题
9.@Slf4j
相当于private static final Logger log = LoggerFactory.getLogger(xxx.class);
以后想生成日志直接调对象,不用创建log对象了
- 感谢你赐予我前进的力量