SpringBoot
1、SpringBoot简介
SpringBoot是一个javaweb的开发框架,简化开发,约定大于配置!
SpringBoot的主要优点:
- 让Spring开发者更快的入门
- 开箱即用,提供各种默认配置来简化项目配置
- 内嵌式容器简化Web项目
- 没有冗余代码生成和XML配置的要求
2、微服务简介
- 单体架构:打包成一个独立的单元(导入一个jar包或者是一个war包)部署完成应用之后,应用通过一个进程的方式来运行,例如,MVC三层架构
- 微服务架构:一个大型的复杂软件应用,由一个或者多个微服务组成,系统中的各个微服务可以被独立部署,各个微服务之间是松耦合的,每个微服务仅仅关注于完成一件任务并很好的完成该任务
3、第一个SpringBoot程序
-
使用idea创建工程
- 1、创建一个新项目
- 2、选择spring initalizr
- 3、填写项目信息
- 4、选择初始化的组件(勾选 Web:Spring Web )
- 5、填写项目路径
- 6、等待项目构建成功
-
项目结构分析src
- main/java底下程序主启动类:TestApplication.java
- main/resources底下配置文件:application.properties,语法结构 :key=value,只能键值对,中文会有乱码 , 我们需要去IDEA中设置编码格式为UTF-8;更推荐使用application.yaml
- test/java底下测试类:TestApplicationTests.java
- pom.xml依赖:
- spring-boot-starter-parent核心依赖,导入依赖默认是不需要写版本,但是如果导入的包没有在依赖中管理着就需要手动配置版本
- spring-boot-starter-xxx是spring-boot的场景启动器,要用什么功能就导入什么样的场景启动器即可,例如spring-boot-starter-web帮我们导入了web模块正常运行所依赖的组件
-
编写一个http接口
-
在主程序的同级目录新建controller包
-
在controller包下新建一个HelloController类
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/hello") public String hello(){ return "hello world"; } }
-
-
浏览器访问http://localhost:8080/hello,页面出现hello world
-
点击idea上Maven的Lifecycle/package打成jar包,在target目录下生成一个jar包,可以在任何地方运行
4、yaml语法
- 空格不能省略
- 以缩进来控制层级关系,左边对齐的一列数据都是同一个层级的
- 属性和值的大小写敏感
#数字,布尔值,字符串
k1: v1
#对象、map
k2:
v1:1
v2:2
#对象、map-行内写法
k22: {
v1:1,v2:2}
#数组
k3:
- v1
- v2
#数组-行内写法
k33: [v1,v2]
#使用占位符生成随机数
name: ${
random.uuid}
age: ${
random.int}
#松散绑定:last-name和lastName一样,-后面的字母默认是大写
5、属性赋值
5.1、@Value方式
- 实体类 Dog
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//注册bean
@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dog {
@Value("三七")
private String name;
@Value("2")
private Integer age;
}
- 测试类中测试
@SpringBootTest
class TestApplicationTests {
@Autowired
private Dog dog;
@Test
void contextLoads() {
System.out.println(dog);
}
}
//控制台打印:Dog(name=三七, age=2)
5.2、yaml注入方式
- 在springboot项目中的resources目录下新建一个文件 application.yaml
cat:
name: 二十一
age: 1
- 实体类Cat
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
//注册bean
@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
//将配置文件中配置的每一个属性的值,映射到这个组件中,prefix指定key
@ConfigurationProperties(prefix = "cat")
public class Cat {
private String name;
private Integer age;
}
- pom.xml导入依赖
<!-- 导入配置文件处理器,需要重启idea -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
- 测试类中测试
@SpringBootTest
class TestApplicationTests {
@Autowired
private Cat cat;
@Test
void contextLoads() {
System.out.println(cat);
}
}
//控制台打印:Cat(name=二十一, age=1)
5.3、指定配置文件方式
- 在springboot项目中的resources目录下新建一个文件 pig.properties
name=小猪
age=1
- 实体类Pig
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
//注册bean
@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
//加载指定的配置文件
@PropertySource("classpath:pig.properties")
public class Pig {
//指定属性值
@Value("${name}")
private String name;
@Value("${age}")
private Integer age;
}
- 测试类中测试
@SpringBootTest
class TestApplicationTests {
@Autowired
private Pig pig;
@Test
void contextLoads() {
System.out.println(pig);
}
}
//控制台打印:Pig(name=小猪, age=1)
6、JSR303数据校验
- pom.xml导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- people.yaml
people:
name: 小雷
age: 18
email: [email protected]
- 实体类People
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "people")
//@Validated数据校验
@Validated
public class People {
@NotNull(message = "用户名不能为空")
private String userName;
@Max(value = 100,message = "年龄不能超过100岁")
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 对象是否符合正则表达式的规则
* */
7、多环境配置
7.1、使用properties
新建application-test.properties 代表测试环境配置
新建application-dev.properties 代表开发环境配置
springboot默认使用application.properties,需要在改该文件里指定使用的环境
spring.profiles.active=dev
7.2、使用yaml多文档块
不需要创建多个yaml,只需要在application.yaml中配置多个环境即可
#选择要激活那个环境块
spring:
profiles:
active: dev
---
server:
port: 8082
spring:
profiles: dev #配置环境的名称
---
server:
port: 8083
spring:
profiles: prod #配置环境的名称
8、SpringBoot Web开发
8.1、静态资源映射规则
8.1.1、webjars
访问:localhost:8080/webjars/xxx
-
idea中按shift+shift,搜索WebMvcAutoConfigurationAdapter类(SpringBoot中,SpringMVC的web配置类),有一个方法addResourceHandlers是用来添加资源处理
-
所有的 /webjars/** , 都需要去 classpath:/META-INF/resources/webjars/ 找对应的资源
-
Webjars本质就是以jar包的方式引入静态资源 ,直接导入即可
-
例如,pom.xml中引入jquery,访问http://localhost:8080/webjars/jquery/3.4.1/jquery.js即可
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
registration.addResourceLocations(new Resource[]{
resource});
}
});
}
}
8.1.2、resources、static、public
访问:localhost:8080/xxx
- ResourceProperties类可以设置和我们静态资源有关的参数,指向了它会去寻找资源的文件夹
以下四个目录存放的静态资源都可以被识别,优先级resources>static>public
"classpath:/META-INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"
resources根目录下新建对应的文件夹,都可以存放我们的静态文件
8.2、首页、图标、404定制
-
页面:
- 在resources下的文件夹下,新建index.html,被 /** 映射
- 访问http://localhost:8080/展示index页面
-
图标:
-
在resources下的文件夹下,放入图标文件favicon.ico
-
关闭SpringBoot默认图标
spring.mvc.favicon.enabled=false
-
清除浏览器缓存,刷新网页显示图标
-
-
404页面:
- 在template文件夹下创建error文件夹,创建404.html页面,访问到未知url时,springboot会自动显示404页面
8.3、Thymeleaf模板引擎
8.3.1、Thymeleaf使用方法
-
pom.xml导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
-
只需要把页面放在templates底下就可以被自动识别
-
在templates下新建test.html
<!DOCTYPE html> <!--导入thymeleaf命名空间的约束--> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--th:text将div中的内容设置为它指定的值--> <div th:text="${msg}"></div> </body> </html>
-
controller
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class TestController { @RequestMapping("/test") public String test(Model model){ //存入数据 model.addAttribute("msg","thymeleaf模板引擎测试"); //classpath:/templates/test.html return "test2"; } }
-
浏览器访问http://localhost:8080/test,展示test.html的内容,msg值为controller中传入的
-
8.3.2、Thymeleaf语法
参考网上即可…
- th属性,常用th属性如下:
- th:text:文本替换
- th:utext:支持html的文本替换
- th:value:属性赋值
- th:each:遍历循环元素
- th:if:判断条件,类似的还有th:unless,th:switch,th:case
- th:insert:代码块引入,类似的还有th:replace,th:include,常用于公共代码块提取的场景
- th:fragment:定义代码块,方便被th:insert引用
- th:object:声明变量,一般和*{}一起配合使用,达到偷懒的效果
- th:attr:设置标签属性,多个属性可以用逗号分隔
8.4、员工管理系统实战-无数据库
无数据库,使用模拟数据(首页、登录拦截、增删改查、404页面)
链接:https://pan.baidu.com/s/1pL55cudzdVC-gPUpJM9_gw
提取码:8qzo
9、SpringBoot整合数据库
9.1、整合JDBC
- pom.xml导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
- application.yaml配置
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/ums?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
- dataSource连接测试
@Autowired
DataSource dataSource;
@Test
void contextLoads() throws SQLException {
Connection connection = dataSource.getConnection();
connection.close();
}
- JdbcTemplate增删改查
@Autowired
JdbcTemplate jdbcTemplate;
/**
* Spring Boot默认提供了数据源,默认提供了JdbcTemplate
* JdbcTemplate自动注入数据源,自动连接和关闭,用于简化JDBC操作
*
* 查询query、queryForXXX
* 新增、修改、删除:update、batchUpdate
* 执行DDL语句:execute,例如create、alter、drop、truncate
* 执行存储过程、函数相关语句:call
*/
@Test
void contextLoads2() throws SQLException {
//查询
List<Map<String, Object>> maps = jdbcTemplate.queryForList("select * from employee");
System.out.println(maps);
//新增
jdbcTemplate.update("insert into employee(ename, email, gender, birthday, did) VALUES ('test', '[email protected]', 1, '2022-03-11 10:39:42', 101)");
//修改
Object[] objects = new Object[2];
objects[0]="姓名修改";
objects[1]=1;
jdbcTemplate.update("update employee set ename=? where id=?",objects);
//删除
Object[] objects1 = new Object[1];
objects[0]=1;
jdbcTemplate.update("delete employee where id=?",objects1);
}
9.2、整合Druid
Druid是监控 DB 池连接和 SQL 的执行情况连接池
- pom.xml导入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<!--监控用到-->
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
- application.yaml配置
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/ums?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource # 自定义数据源
#Spring Boot默认不注入以下属性,需要自己绑定
#druid数据源专有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
- Druid配置类:数据源属性注入、数据源监控、监控过滤器
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
@Configuration
public class DruidConfig {
/**
* 将自定义的 Druid数据源添加到容器中,不再让SpringBoot自动创建
* 将全局配置文件中前缀为spring.datasource的属性值注入到com.alibaba.druid.pool.DruidDataSource的同名参数中
*/
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource