瞻山识璞,临川知珠
1. 概述
- 定义
SpringBoot是一个基于Spring4.0的javaweb快速开发框架,策略:开箱即用和约定优于配置,作者:Pivotal团队
- 与SSM区别
序号 | SSM | SpringBoot |
---|---|---|
1 | Tomcat:war包 | 内嵌Tomcat :jar包 |
- 微服务
微服务是一种高内聚,低耦合架构风格,James Lewis,Martin Fowler
- SpringBoot 2.7.8要求
工具 | Version |
---|---|
jdk | Java 8 |
Spring Framework | 5.3.25 |
Maven | 3.5+ |
Gradle | 6.8.x, 6.9.x, and 7.x |
Tomcat 9.0 | 4.0 |
Jetty 9.4 | 3.1 |
Jetty 10.0 | 4.0 |
Undertow 2.0 | 4.0 |
2. 项目结构分析
2.1 创建方式
- 阿里云镜像导入
- spring官网导入
- idea创建(推荐)选择spring initalizr
2.2 项目结构
1、程序的主启动类(程序的主入口)
2、一个 application.properties 配置文件(SpringBoot的核心配置文件)
3、一个 测试类
4、一个 pom.xml
- pom.xml
1 |
|
2.3 修改配置
- 修改端口
1 | server.port=8081 |
- 修改运行图标
banner.txt
1 | __ |
3. 原理初探
3.1 自动配置
pom.xml文件
- spring-boot-starter-parent 核心依赖在父工程中spring-boot-dependencies,锁定了版本,不需要写版本
1 | <parent> |
- 启动器【springBoot 启动场景】
- spring-boot-starter,我们需要什么功能,找到对应的启动器就可以了,
starter
,比如spring-boot-starter-web就是自动导入web环境所有依赖
- spring-boot-starter,我们需要什么功能,找到对应的启动器就可以了,
1 | <dependency> |
- 主程序
1 | package com.xxy.helloworld; |
@SpringBootApplication下的注解
springboot配置
@SpringBootConfiguration
spring自动配置 全面接管SpringMVC的配置
@EnableAutoConfiguration
springboot自动配置扫描:有判断条件,只有导入了先对应的start,自动装配才会生效
@ComponentScan
1
2
3
4
5
6
7
8
9
10
11
12
13//springboot的配置 .springframework.boot.SpringBootConfiguration
- //spring 配置类
-- //说明者也是一个Spring的组件
//自动配置ioc注入类 .springframework.boot.autoconfigure.EnableAutoConfiguration
- //自动配置包
--//自动配置 ‘包注册’
- //自动配置导入选择器
//获取所有(候选)的配置
-- protected List<String> getCandidateConfigurations AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");//自动配置中的核心文件
return configurations;
}结论:
springboot所有自动配置都是启动时进行加载:spring.factories,里面有判断条件,条件不满足,就会无效,有了启动器,自动装配才会生效;
自动装配的原理
- SpringBoot启动会加载大量的自动配置类
- 寻找我们的功能是否在默认自动配置中
- 查看自动配置类中配置了哪些组件 (没有就需要手动配置)
- 添加组件时会从properties类中获取一部分属性
- XX AutoConfigurartion:给容器添加组件
- XX Properties:封装配置文件的属性,.yaml
- 可以通过yml文件
debug: true
来查看自动配置的生效
3.2 SpringApplication类
- SpringApplication做了下面四件事
推断应用的类型是普通的项目还是Web项目
查找并加载所有可用初始化器 , 设置到initializers属性中
找出所有的应用程序监听器,设置到listeners属性中
推断并设置main方法的定义类,找到运行的主类
1 | public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) { |
- run():
①配置环境参数
②推断并设置main方法的定义类,找到运行的主类
③run方法里面有一些监听器,这些监听器是全局存在的,它的作用是获取上下文处理一些bean,所有的bean无论是加载还是生产初始化多存在。
3.3 自动配置加深
- 自动配置原理
Spring Boot通过@EnableAutoConfiguration注解开启自动配置,对jar包下的spring.factories文件进行扫描,这个文件中包含了可以进行自动配置的类,当满足@Condition注解指定的条件时,便在依赖的支持下进行实例化,注册到Spring容器中。
通俗的来讲,springboot的自动配置就是用注解来对一些常规的配置做默认配置,简化xml配置内容,使你的项目能够快速运行。
- @Conditional派生注解
序号 | 注解名称 | 作用 |
---|---|---|
1 | @Conditional | 作用(判断是否满足当前指定条件) |
2 | @ConditionalOnJava | 系统的java版本是否符合要求 |
3 | @ConditionalOnBean | 容器中存在指定Bean |
4 | @ConditionalOnMissingBean | 容器中不存在指定Bean |
5 | @ConditionalOnExpression | 满足SpEL表达式指定 |
6 | @ConditionalOnClass | 系统中有指定的类 |
7 | @ConditionalOnMissingClass | 系统中没有指定的类 |
8 | @ConditionalOnSingleCandidate | 容器中只有一个指定的Bean,或者这个Bean是首选Bean |
9 | @ConditionalOnProperty | 系统中指定的属性是否有指定的值 |
10 | @ConditionalOnResource | 类路径下是否存在指定资源文件 |
11 | @ConditionalOnWebApplication | 当前是web环境 |
12 | @ConditionalOnNotWebApplication | 当前不是web环境 |
13 | @ConditionalOnJndi | JNDI存在指定项 |
4. 注入配置文件
结论:用yaml更好,除了SPEL表达式;如果yml和properties同时都配置了端口,默认会使用properties配置文件的!
4.1 导入文件处理器
1 | <!-- 防止@ConfigurationProperties(prefix = "person")注入报红--> |
4.2 编写配置文件
- application.properties文件
1 | # Spring Boot配置文件,修改SpringBoot自动配置的默认值 |
- application.yaml文件
1 | # Spring Boot yaml配置 |
4.3 进行绑定注入
1 |
|
1 |
|
4.4 松散绑定
yaml可以是-和_和驼峰式命名相互绑定,根据set方法赋值
4.5 JSR303校验
@Validated//Spring数据验证 @Valid:JDK提供的(标准JSR-303规范),不知道用哪个可以直接找源码javax.validation.constraints
1 | <!--jsr303验证--> |
约束注解名称 | 约束注解说明 |
---|---|
@Null | 用于验证对象为null |
@NotNull | 用于对象不能为null,无法查检长度为0的字符串 |
@NotBlank | 只用于String类型上,不能为null且trim()之后的size>0 |
@NotEmpty | 用于集合类、String类不能为null,且size>0。但是带有空格的字符串校验不出来 |
@Size | 用于对象(Array,Collection,Map,String)长度是否在给定的范围之内 |
@Length | 用于String对象的大小必须在指定的范围内 |
@Pattern | 用于String对象是否符合正则表达式的规则 |
用于String对象是否符合邮箱格式 | |
@Min | 用于Number和String对象是否大等于指定的值 |
@Max | 用于Number和String对象是否小等于指定的值 |
@AssertTrue | 用于Boolean对象是否为true |
@AssertFalse | 用于Boolean对象是否为false |
@Past | 验证 Date 和 Calendar 对象是否在当前时间之前 |
@Future | 验证 Date 和 Calendar 对象是否在当前时间之后 |
4.6 配置文件yaml优先级(从高到低);互补配置;可以通过spring.config.location改变默认位置
– file:./config/
– file:./
–classpath:/config/
–classpath:/
4.7 配置文件服务端口配置(建议)
1 | # 设置服务器端口号 |
5. SpringBoot Web开发
5.1 静态资源
- WebMvcAutoConfiguration类源码
1 | //源码 |
引入jquery静态资源
1 | <!--引入jquery包--> |
静态资源放的位置:(优先级从高到低),自己定义路径
1 | # 自定义静态资源位置 |
- 导入依赖包,classpath:/META-INF/resources/webjars/
- classpath:/resources/
- classpath:/static/(默认)
- classpath:/public/
- /**
5.2 首页
- 源码
1 |
|
1 | package com.xxy.controller; |
5.3 模板引擎(比较少用,大多数前后端分离,用来渲染,vue使用pug)
1 | <!--导入Thymeleaf模板引擎--> |
5.4 装配扩展SpringMVC
- 自定义视图解析器
1 | package com.xxy.config; |
- 视图跳转
1 | package com.xxy.config; |
5.5 增删改查
- controlller Restful风格
1 |
|
- 错误信息
在templates建立error包,然后404,500文件
5.6 国际化
- 在资源文件夹建立i18u文件夹
- 建立login.properties和login_zh_CN.properties
- 他们会自动合并为一个文件夹中,新建login_en_US.properties文件
- login_en_US.properties写入内容进行翻译
- 自定义组件
1 | package com.xxy.config; |
- 注册bean到Spring容器
1 |
|
- 前端渲染显示
6. Data
6.1 SpringData
对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理
6.2 整合JDBC
- 导入依赖
1 | <dependency> |
- 进行配置
1 | spring: |
- 使用原始jdbc进行开发
1 |
|
- 使用SpringBoot封装的jdbcTemplate
1 |
|
6.3 整合JDBC数据连接池
- 概述
HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀;Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源
- 导入依赖
1 | <dependency> |
- 配置
1 | spring: |
- 进行扩展
1 |
|
6.4 整合Mybatis
- 概述
MyBatis-Spring-Boot-Starter | MyBatis-Spring | Spring Boot | Java |
---|---|---|---|
3.0 | 3.0 | 3.0 | 17 或更高 |
2.3 | 2.1 | 2.5 - 2.7 | 8 或更高 |
2.2 | 2.0(2.0.6 以上可开启所有特性) | 2.5 - 2.7 | 8 或更高 |
2.1 | 2.0(2.0.6 以上可开启所有特性) | 2.1 - 2.4 | 8 或更高 |
- 导入依赖
1 | <dependency> |
- 进行配置
1 | spring: |
- 进行开发模块
- User
1 |
|
- UserMapper
1 | package com.xxy.mapper; |
- UserMapper.xml
1 |
|
- UserService
1 | package com.xxy.service; |
- UserServiceImpl
1 | package com.xxy.service; |
- UserController
1 | package com.xxy.controller; |
7. SpringSecurity
7.1 简述
一个安全的框架,其实通过过滤器和拦截器也可以实现,主要是用户认证和授权
- 用户认证
在用户认证方面,Spring Security 框架支持主流的认证方式,包括 HTTP 基本认证、HTTP 表单验证、HTTP 摘要认证、OpenID 和 LDAP 等。
- 用户授权
在用户授权方面,Spring Security 提供了基于角色的访问控制和访问控制列表(Access Control List,ACL),可以对应用中的领域对象进行细粒度的控制。
7.2 使用
- 导依赖
1 | <!--SpringSecurity --> |
- 配置和扩展
1 | //@EnableWebSecurity:开启WebSecurity模式 |
- 开发
1 |
|
8.Shiro
8.1 简介
- 定义
Apache Shiro是一个强大且易用的Java安全框架,可以完成身份验证、授权、密码和会话管理
- 功能
- Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
- Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
- Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
- Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储
- Web Support:Web支持,可以非常容易的集成到Web环境;
- Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
- Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
- Testing:提供测试支持;
- Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
- Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
- 外部架构
- Subject:主体,代表了当前“用户”,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等;即一个抽象概念;所有Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager;可以把Subject认为是一个门面;SecurityManager才是实际的执行者;
- SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager交互;且它管理着所有Subject;可以看出它是Shiro的核心,它负责与后边介绍的其他组件进行交互,如果学习过SpringMVC,你可以把它看成DispatcherServlet前端控制器;
- Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。
8.2 认证
- 导入依赖
1 | <dependency> |
- 扩展或配置
- UserRealm
1 | public class UserRealm extends AuthorizingRealm { |
- ShiroConfig
1 |
|
- 开发
- ShiroController
1 |
|
- 前端
- templeats文件夹新建shiro文件夹,在shiro文件夹新建user文件夹
- shiro文件夹主页index.html
1 |
|
- shiro文件夹login.html
1 |
|
- user文件夹更新和增加insert.html、update.html
1 |
|
8.3 整合Mybatis
- 修改UserRealm
1 | public class UserRealm extends AuthorizingRealm { |
8.4 授权
- 前端
- update.html
1 |
|
- ShiroConfig
1 |
|
- controller
1 |
|
9. Swagger
9.1 简述
- 定义
Swagger 是一个规范且完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
- 优点
- 支持多种语言
- 直接运行,在线测试API接口(其实就是controller requsetmapping)
- 注解
序号 | 注解名称 | 功能 | 备注 |
---|---|---|---|
1 | @Api() | 用于类,标识这个类是swagger的资源 | |
2 | @ApiOperation() | 用于方法,描述 Controller类中的 method接口 | |
3 | @ApiParam() | 用于参数,单个参数描述,与 @ApiImplicitParam不同的是,他是写在参数左侧的 | |
4 | @ApiModel() | 用于类,表示对类进行说明,用于参数用实体类接收 | |
5 | @ApiModelProperty() | 用于方法,字段,表示对model属性的说明或者数据操作更改 | |
6 | @ApiIgnore() | 用于类,忽略该 Controller,指不对当前类做扫描 | |
7 | @ApiImplicitParam() | 用于方法,表示单独的请求参数 | |
8 | @ApiImplicitParams() | 用于方法,包含多个 @ApiImplicitParam | |
9 | @ApiResponse | 用于方法,描述单个出参信息 | |
10 | @ApiResponses | 用于方法,包含多个@ApiResponse | |
11 | @ApiError | 用于方法,接口错误所返回的信息 |
9.2 SpringBoot使用
- 导入依赖
1 | <dependency> |
或
1 | <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --> |
- 配置或者扩展
1 | package com.xxy.config; |
- 3.0.0版本需要增加两个注解,不需要@EnableSwagger2
1 | // 可选 |
- 开发
- User.java
1 |
|
- UserController
1 |
|
注意
正式环境或者开发测试结束后应该关闭Swagger,.enable(flag)
10. 任务
10.1 异步任务
- 定义
某些功能实现时可能要花费一定的时间,但是为了不影响客户端的体验,选择异步执行
- 开发
先启用@EnableAsync,在想要异步的方法加 @Async注解
1 |
|
1 |
|
10.2 邮件任务
- 导包
1 | <dependency> |
- 配置
1 | spring.mail.username=你的邮箱 |
- 开发
1 |
|
10.3 定时任务
- 简述接口和注解
TaskExecutor接口和TaskScheduler接口 注解:@EnableScheduling和@Scheduled
- cron
- cron生成器
- 常规用法
1 | //秒 分 时 日 月 周几 |
- 特殊字符
序号 | 符号 | 意思 | 备注 |
---|---|---|---|
1 | * | 每个 | |
2 | ? | 不确定值 | |
3 | - | 指定范围 | |
4 | L | 只用在DayofMonth和DayofWeek中,这个字符是“Last”的简写,重要的是不要指定列表或者值范围,否则会导致混乱。 | |
5 | W | 指定给定日(星期一到星期五)最近的一天 | |
6 | # | 表示本月中的第几个周几 | |
7 | , | 表达一个列表值 | |
8 | / | 如 x/y,x 是开始值,y 是步长 | |
9 | C | 和Calendar计算过的值 |
- 开发
- 在主程序加上
@EnableScheduling
注解
1 |
|
11 SpringBoot和Redis
11.1 概述
- SpringBoot操作数据: Spring-data jpa jdbc mongdb redis
- springboot 2.x后 ,原来使用的 Jedis 被 lettuce 替换。
1 | //LettuceConnectionFactory |
jedis:采用的直连,多个线程操作的话,是不安全的。如果要避免不安全,使用jedis pool连接池!更像BIO模式
lettuce:采用netty,实例可以在多个线程中共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式
11.2 Redis在SpringBoot中的自动配置
- 找到org.springframework.boot.autoconfigure包下的spring-boot-autoconfigure-2.5.0.jar!\META-INF\spring.factories,搜索redis
- 存在一个xxxAutoConfiguration和RedisProperties
- 若要修改配置查看RedisProperties
1 | @ConfigurationProperties( |
11.3 测试
- 导入依赖
1 | <!--操作redis--> |
- 配置
1 | spring.redis.host=127.0.0.1 |
- 自定义序列化模板
1 |
|
- 编写代码
1 |
|
12. 分布式Dubbo和Zookeeper集成
12.1 分布式简述
- 定义
分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统, 分布式系统(distributed system)是建立在网络之上的软件系统。其目的是利用更多的机器,处理更多的数据。
- 为什么使用
首先需要明确的是,只有当单个节点的处理能力无法满足日益增长的计算、存储任务的时候,且硬件的提升(加内存、加磁盘、使用更好的CPU)高昂到得不偿失的时候,应用程序也不能进一步优化的时候,我们才需要考虑分布式系统。
12.2 Dubbo
- 背景
- 单一应用架构
性能扩展比较难、协同开发问题、不利于升级维护
- 垂直应用架构(MVC)
公用模块无法重复利用,开发性的浪费
- 分布式服务架构
提高业务复用及整合的**分布式服务框架(RPC)**是关键。
- 流动计算架构
提高机器利用率的资源调度和治理中心(SOA)[ Service Oriented Architecture]是关键。
- 定义
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案
- 核心
- 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
- 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
- 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
- 调用关系
服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者(Consumer 发布订阅设计模式):调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
- RPC
RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。
- RPC核心
- 通讯:协议
- 序列化
- 推荐文章
12.3 Zookeeper
- 定义
是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。文件系统+监听通知机制。
12.4 开发
需要打开Zookeeper,如果需要监控dubbo-admin-0.0.1-SNAPSHOT.jar
- 导包
1 | <!-- 引入zookeeper --> |
- 配置或扩展
1 | #当前应用名字 |
- 开发
1 | import org.apache.dubbo.config.annotation.Service; |
- 另外服务消费者导包
1 | <!--dubbo--> |
- 消费者配置
1 | #当前应用名字 |
- 消费者开发
1 | package com.guo.consumer.service; |
- 测试
1 |
|
13. 总结
本次系统学习了SpringBoot,下面开始学习SpringCloud,将往API网关【服务路由】、Http、RPC框架【异步调用】、服务注册与发现【高可用】、熔断机制【服务降级】方向发展