spring boot

第1章 Spring Boot概要

1.1 SpringBoot介绍

随着动态语言的流行(Ruby、Scala、Node.js), Java的开发显得格外的笨重;繁多的配置、低下的开发效率、复杂的部署流程以及第三方技术整合难度大。

在上述环境下,Spring Boot由此诞生,它的设计是为了使您能够尽可能快地启动和运行。它使用 “习惯优于配置” (项目中存在大量的配置,而 Spring Boot 内置一个习惯性的配置,让你无须手动进行配

置)的理念让你的项目快速运行起来。使用 Spring Boot 很容易创建一个独立运行(运行jar,内嵌

Servlet 容器)、准生产强力的基于 Spring 框架的项目,使用 Spring Boot你可以不用或者只需要很少的 Spring 配置。提供了 J2EE 开发的一站式解决方案。

2014 年 4 月,Spring Boot 1.0.0 发布。Spring的顶级项目之一(https://spring.io)。

1.2 SpringBoot优点
  • Create stand-alone Spring applications
    • 创建独立Spring应用
  • Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
    • 内嵌web服务器
  • Provide opinionated 'starter' dependencies to simplify your build configuration
    • 自动starter依赖,简化构建配置
    • 起步依赖,起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。简单的说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能
  • Automatically configure Spring and 3rd party libraries whenever possible
    • 自动配置Spring以及第三方功能
  • Provide production-ready features such as metrics, health checks, and externalized configuration
    • 提供生产级别的监控、健康检查及外部化配置
  • Absolutely no code generation and no requirement for XML configuration
    • 无代码生成、无需编写XML

SpringBoot是整合Spring技术栈的一站式框架

SpringBoot是简化Spring技术栈的快速开发脚手架

Spring Boot 并不是对 Spring 功能上的增强,而是提供了一种快速使用 Spring 的方式

1.3 SpringBoot缺点
  • 人称版本帝,迭代快,需要时刻关注变化
  • 封装太深,内部原理复杂,不容易精通
1.4 时代背景-微服务

James Lewis and Martin Fowler (2014)提出微服务完整概念。https://martinfowler.com/microservices/

In short, the microservice architectural style is an approach to developing a single

application as a suite of small services, each running in its own process and

communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully

automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming

languages and use different data storage technologies.-- James Lewis and Martin Fowler (2014)

  • 微服务是一种架构风格
  • 一个应用拆分为一组小型服务
  • 每个服务运行在自己的进程内,也就是可独立部署和升级
  • 服务之间使用轻量级HTTP交互
  • 服务围绕业务功能拆分
  • 可以由全自动部署机制独立部署
  • 去中心化,服务自治。服务可以使用不同的语言、不同的存储技术
1.5 如何学习SpringBoot

官网文档架构

查看版本新特性;

https://github.com/spring-projects/spring-boot/wiki#release-notes

第2章Spring Boot入门开发

技术点要求

熟练 Spring 框架的使用

熟练 Maven 依赖管理与项目构建熟练使用 Eclipse 或 IDEA

2.1 环境要求
环境准备:
  • java version "1.8.0_181"
  • Maven-3.6.1
  • SpringBoot 2.x 最新版

2.2 快速构建SpringBoot项目

项目创建方式一:使用Spring Initializr 的 Web页面创建项目

1. 打开https://start.spring.io/

2. 填写项目信息

3. 点击”Generate Project“按钮生成项目;下载此项目

4. 解压项目包,并用IDEA以Maven项目导入,一路下一步即可,直到项目导入完毕。

5. 如果是第一次使用,可能速度会比较慢,包比较多、需要耐心等待一切就绪。

项目创建方式二:使用 IDEA 直接创建项目

1. 创建一个新项目

2. 选择spring initalizr ,可以看到默认就是去官网的快速构建工具那里实现

3. 填写项目信息

4. 选择初始化的组件(初学勾选 Web 即可)

5. 填写项目路径

6. 等待项目构建成功

项目创建方式三:使用 IDEA 直接创建项目

1. 与方式2相同,但是参考路径为:https://start.aliyun.com

项目创建方式四:使用 IDEA 创建Maven项目并改造为springBoot项目结构分析:

1. 程序的主启动类

2. 一个 application.properties 配置文件

3. 一个测试类

4. 一个 pom.xml

2.2.1 实现处理请求案例

1、在主程序的同级目录下,新建一个controller包,一定要在同级目录下,否则识别不到

2、在包中新建一个HelloController类

3、编写完毕后,从主程序启动项目,浏览器发起请求,看页面返回;控制台输出了 Tomcat 访问的端口号!

2.2.2 项目打jar包

使用指令 java -jar 项目名

2.2.3 banner修改

1. 项目下的 resources 目录下新建一个banner.txt 即可。

2. 图案可以到:https://www.bootschool.net/ascii这个网站生成,然后拷贝到文件中即可!

3. 设置图片作为banner

spring.banner.image.location=logo.png

2.2.4 项目列表显示优化

2.3 运行原理初步探究

1. spring-boot-starter-parent

  • springBoot项目都要继承spring-boot-starter-parent
  • spring-boot-starter-parent中定义了若干个依赖管理
  • 继承parent模块可以避免多个依赖使用相同技术时出现依赖冲突
  • 继承parent的形式也可以采用引入依赖的形式实现效果例如alibaba

2. start

  • 导入套餐形式的坐标从而简化配置,坐标实现依赖传递

3. 引导类

  • 程序主入口,初始化spring容器,扫描所有类
  • 可以通过run方法返回值获取bean检验

4. 内嵌tomcat

第3章 Spring Boot 核心配置

3.1 Spring Boot配置文件分类

SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用

application.properties或者application.yml(application.yaml)进行配置

  • application.properties
    • 语法结构:key=value
  server.port=8081

application.yml

    • 语法结构:key:空格 value (冒号后面必须要有空格)
server:
 	port: 8081

小结

  • SpringBoot提供了2种配置文件类型:properteis和yml/yaml
  • 默认配置文件名称:application
  • 在同一级目录入如果三类文件共存,优先级为:properties > yml > yaml
3.2 YAML概述

YAML全称是 YAML Ain't Markup Language 。YAML是一种直观的能够被电脑识别的的数据数据序列化格式,

并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,比如:

C/C++, Ruby, Python, Java, Perl, C#, PHP等。YML文件是以数据为核心的,比传统的xml方式更加简洁。

YAML文件的扩展名可以使用.yml或者.yaml。

properties:

server.port=8080
server.address=127.0.0.1

xml:

<server> 
 <port>8080</port> 
 <address>127.0.0.1</address> 
</server> 

yml:

server: 
 port: 8080 
 address: 127.0.0.1 

简洁,以数据为核心

3.3 YAML基础语法

1. 大小写敏感

2. 数据值前边必须有空格,作为分隔符 3. 使用缩进表示层级关系

4. 缩进时不允许使用Tab键,只允许使用空格(各个系统 Tab对应的空格数目可能不同,导致层次混乱)。

5. 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

6. "#"表示注释,从这个字符一直到行尾,都会被解析器忽略。

YAML:数据格式

  • 字面量:普通的值 [ 数字,布尔值,字符串 ]
boolean: TRUE #TRUE,true,True,FALSE,false,False均可
float: 3.14 #6.8523015e+5 #支持科学计数法
int: 123 #0b1010_0111_0100_1010_1110 #支持二进制、八进制、十六进制
string: HelloWorld #字符串可以直接书写
  • 数组:一组按次序排列的值( List、set )
address:
 - beijing
 - shanghai
# 行内写法
commpany: [阿里巴巴,华为,腾讯,字节跳动]
  • 对象、Map(键值对)
person:
 name: wangzhuo
# 行内写法
person: {name: wangzhuo}
#对象数组格式一
users:
 - name: Tom
 age: 4
 - name: Jerry
 age: 5
  
#对象数组格式二
users: 
 -
 name: Tom
 age: 4
 -
 name: Jerry
 age: 5 
#对象数组缩略格式
users2: [ { name:Tom,age:4 },{ name:Jerry,age:5 } ]

YAML:参数引用

name: wangzhuo
person:
 name: xuelaoshi 
 pet: ${name} # 引用上边定义的name值
 name: xuls${random.uuid} # 配置文件占位符,随机uuid
 name: ${person.name}_真帅

YAML:小结

1)配置文件类型

  • properties:和以前一样 (设置文件的语言编码UTF-8)
  • yml/yaml:注意空格

2) yaml:简洁,以数据为核心

  • 基本语法
    • 大小写敏感
    • 数据值前边必须有空格,作为分隔符
    • 使用空格缩进表示层级关系,相同缩进表示同一级
  • 数据格式
    • 对象
    • 数组: 使用 " - "表示数组每个元素
    • 纯量
  • 参数引用
    • ${key}
3.4 读取配置内容

yaml文件更强大的地方在于,他可以给我们的实体类直接注入匹配值!支持方式:

逐个注入:@Value

批量注入:1.@ConfigurationProperties

2.Environment类

逐个注入演示

@Component //注册bean
public class Dog {
    @Value("阿黄")
    private String name;
    @Value("18")
    private Integer age;
}

加载指定的配置文件@PropertySource :加载指定的配置文件;

我们去在resources目录下新建一个dog.yml文件

name: 阿黄
age: 18 
@PropertySource(value = "classpath:dog.yml")
@Component //注册bean
public class Dog{
    @Value("${name}")
    private String name;
    @Value("${age}")
    private Integer age; 
}

批量注入方式1

编写一个复杂一点的实体类:Person 类

@Component //注册bean到容器中
public class Person {
    
    private String name;
    private integer age;
    private boolean marry;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;
    
    //有参无参构造、get、set方法、toString()方法  
}

编写yaml文件内容

person1:
 name: wangls
 age: 18
 marry: true
 birth: 1990/10/19
 maps: {k1: v1,k2: v2}
 lists:
   - code
   - bodybuilding
   - music
 dog:
   name: summer
   age: 1

将数据注入到我们的类中

/*
@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应
*/
@Component //注册bean
@ConfigurationProperties(prefix = "person1")
public class Person {
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;
} 

如果编写完配置文件有红色提示,则可以添加坐标隐藏

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-configuration-processor</artifactId>
  <optional>true</optional>
</dependency>

测试类中测试一下

@SpringBootTest
class DemoApplicationTests {
    @Autowired
    Person person; //将person自动注入进来
    @Test
    public void contextLoads() {
        System.out.println(person); //打印person信息
   }
}

批量注入方式2

直接在测试类中装配开发模式类辅助获取key对应value数据

@Autowired
private Environment env;
@Test
public void test(){ 
    System.out.println(env.getProperty("person1.name"));
    System.out.println(env.getProperty("person1.age"));
    System.out.println(env.getProperty("person1.dog.name"));
    System.out.println(env.getProperty("person1.lists[0]"));    
}

对比小结

@Value这个使用起来并不友好!我们需要为每个属性单独注解赋值,比较麻烦;我们来看个功能对比图

对比

@ConfigurationProperties

@Value

功能

批量注入配置文件中的属性

一个个指定

松散语法

支持

不支持

SpEL

不支持

支持

JSR303数据校验

支持

不支持

复杂类型封装

支持

不支持

1、@ConfigurationProperties只需要写一次即可, @Value则需要每个字段都添加

2、松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下

3、JSR303数据校验,这个就是我们可以在字段是增加一层过滤器验证,可以保证数据的合法性

4、复杂类型封装,yml中可以封装对象,使用value就不支持

结论:

配置yml和配置properties都可以获取到值,强烈推荐 yml;

如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;

如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties,不要犹豫!

3.5 JSR303数据校验

对于web服务来说,为防止非法参数对业务造成影响,在Controller层一定要做参数校验的!大部分情况下,请求参数分为如下两种形式:

1. POST、PUT请求,使用requestBody传递参数;

2. GET请求,使用requestParam/PathVariable传递参数。

什么是 JSR303 标准?

JSR的全称是Java Specification Requests(Java 规范提案),是指向JCP ( Java Community Process )提出

新增一个标准化技术规范的正式请求。

Java API规范(JSR303)定义了Bean校验的标准validation-api,但没有提供实现。hibernate validation是对这个规范的实现,并增加了校验注解如@Email、@Length等。Spring Validation是对hibernate validation的二次封装,用于支持spring mvc参数自动校验。接下来,我们以spring-boot项目为例,介绍Spring Validation的使用

JSR303校验注解的使用步骤

1.添加依赖,导入spring-boot-starter-validation启动器

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2.在实体类需要校验的成员字段(Field)上,添加校验注解。

@Component  //注册bean到容器中
//@ConfigurationProperties(prefix = "dog")
//@Validated
public class Dog {
    @NotNull(message = "狗名不能为空")
    private String name;
    @NotNull(message = "狗命不能为空")
    @Max(value = 15,message = "狗命拿来")
    private Integer age;
    @Min(value = -1,message = "狗还是个细胞")
    private Integer length;
    @Email(message = "邮箱必须合法")
    private String email;
}

3.在Controller控制器的校验参数前,使用@Valid注解开启校验,使用BindingResult绑定校验结果

@RequestMapping("/validationDemo")
    public String validationDemo(@Valid Dog dog, BindingResult result){
        //得到所有错误信息计数
        int errorCount = result.getErrorCount();
        //错误数大于0
        if (errorCount>0){
            //得到所有错误
            List<FieldError> fieldErrors = result.getFieldErrors();
            //迭代错误
            for (FieldError fieldError:fieldErrors) {
                //错误信息
                System.out.println( "属性:{},"+fieldError.getField()+"传来的值是:
{}"+fieldError.getRejectedValue()+",出错的提示消息:
{}"+fieldError.getDefaultMessage());
           }
            return "数据不合法";
       }else{
            return "数据合法";
       }
   }
JSR303校验注解的分类

值校验:

// 被注解的元素必须为null
  @Null(message = "必须为null") 
  
  // 被注解的元素必须不为null
  @NotNull(message = "必须不为null") 
  
  // 校验注解的元素值不为空(不为null、去除首位空格后长度为0),类型为String
  @NotBlank(message = "必须不为空") 
  
  // 校验注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0),类型为CharSequence、
Collection、Map、Array
  @NotEmpty(message = "必须不为null且不为空") 
  
  // 被注解的元素必须为true,并且类型为boolean
  @AssertTrue(message = "必须为true") 
  
  // 被注解的元素必须为false,并且类型为boolean
  @AssertFalse(message = "必须为false")

范围校验

// 被注解的元素其值必须大于等于最小值,并且类型为int,long,float,double
@Min(value = 18, message = "必须大于等于18")
// 被注解的元素其值必须小于等于最小值,并且类型为int,long,float,double
@Max(value = 18, message = "必须小于等于18") 
// 校验注解的元素值大于等于@DecimalMin指定的value值,并且类型为BigDecimal
@DecimalMin(value = "150", message = "必须大于等于150") 
// 校验注解的元素值小于等于@DecimalMax指定的value值 ,并且类型为BigDecimal
@DecimalMax(value = "300", message = "必须大于等于300")
// 校验注解的元素值在最小值和最大值之间,并且类型为BigDecimal,BigInteger,CharSequence,
byte,short,int,long。
@Range(max = 80, min = 18, message = "必须大于等于18或小于等于80") 
// 被注解的元素必须为过去的一个时间,并且类型为java.util.Date
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Past(message = "必须为过去的时
间")
// 被注解的元素必须为未来的一个时间,并且类型为java.util.Date
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Future(message = "必须为未来的时
间")

长度校验:

// 被注解的元素的长度必须在指定范围内,并且类型为String,Array,List,Map
@Size(max = 11, min = 7, message = "长度必须大于等于7或小于等于11")
// 校验注解的元素值长度在min和max区间内 ,并且类型为String
@Length(max = 11, min = 7, message = "长度必须大于等于7或小于等于11")

格式校验:

// 校验注解的元素值的整数位数和小数位数上限 ,并且类型为float,double,BigDecimal。
@Digits(integer=3,fraction = 2,message = "整数位上限为3位,小数位上限为2位")
// 被注解的元素必须符合指定的正则表达式,并且类型为String
@Pattern(regexp = "\\d{11}",message = "必须为数字,并且长度为11")
// 校验注解的元素值是Email,也可以通过regexp和flag指定自定义的email格式,类型为String
@Email(message = "必须是邮箱")

Controller统一异常处理

@ControllerAdvice:统一为Controller进行"增强"@ExceptionHandler : 异常处理

import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.*;
@ControllerAdvice
public class BindExceptionUtilAdvice {
    // 验证参数未使用@RequestBody注解
    @ExceptionHandler(BindException.class)
    @ResponseBody//选择添加
    public String handlerBindException(BindException ex, HttpServletRequest 
request){
        
 return "全局异常处理器成功"; // 跳转至统一提示错误信息的视图
   }
}
3.6 多环境切换profile

我们在开发Spring Boot应用时,通常同一套程序会被安装到不同环境,比如:开发、测试、生产等。其中数据库地址、服务器端口等等配置都不同,如果每次打包时,都要修改配置文件,那么非常麻烦。profile功能就是来进行动态配置切换的;

命名语法:

例如:application-环境简称.properties/yml

  • application-dev.properties/yml 开发环境
  • application-test.properties/yml 测试环境
  • application-pro.properties/yml 生产环境

1) profile配置方式

  • 多profile文件方式

2) profile激活方式

  • 配置文件:
spring:
 profiles:
   active:  环境简称
  • 虚拟机参数:在VM options 指定:-Dspring.profiles.active=dev
  • 命令行参数:java –jar xxx.jar --spring.profiles.active=dev

第4章Spring Boot 的Web开发

4.1官网

总结:

只要静态资源放在类路径下: called /static (or /public or /resources or /METAINF/resources

访问 :当前项目根路径/ + 静态资源名

4.2 enjoy模板引擎

1.将页面保存在templates目录下 2.添加坐标

3.开启配置

4.编写代码

4.3 springMVC

1.请求处理 2.参数绑定 3.常用注解 4.数据传递 5.文件上传

4.4 注册Servlet三大组件 Servlet/Filter/Listener

而由于 Spring Boot 默认是以 jar 包的方式运行嵌入式Servlet容器来启动应用,没有web.xml文件,Spring提供以下Bean来注册三大组件

ServletRegistrationBean 注册自定义Servlet

FilterRegistrationBean 注册自定义Filter

ServletListenerRegistrationBean 注册自定义Listener

如果使用传统

@WebFilter...实现注册也可以

条件:1.一定是自定义组件

2.启动类添加@ServletComponentScan

4.5 切换为其他嵌入式Servlet容器

SpringBoot 默认针对Servlet容器提供以下支持:

  • Tomcat(默认使用)
  • Jetty :支持长连接项目(如:聊天页面)[ˈdʒeti]
  • Undertow : 不支持 JSP , 但是并发性能高,是高性能非阻塞的容器[ˈʌndətəʊ]

默认Tomcat容器

在spring-boot-starter-web启动器中默认引入了tomcat容器 
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <version>2.1.0.RELEASE</version>
    <scope>compile</scope>
</dependency>

切换 Jetty 容器

<dependency>
    <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 <!-- 排除tomcat容器 -->
 <exclusions>
        <exclusion>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
    </exclusions>
</dependency>
<!--引入其他的Servlet容器-->
<dependency>
    <artifactId>spring-boot-starter-jetty</artifactId>
    <groupId>org.springframework.boot</groupId>
</dependency>

使用外置Servlet容器Tomcat9.x

  • 嵌入式Servlet容器:运行启动类就可启动,或将项目打成可执行的 jar 包
    • 优点:简单、快捷;
    • 缺点:默认不支持JSP、优化定制比较复杂使用定制器, 还需要知道每个功能的底层原理
  • 外置Servlet容器:配置 Tomcat, 将项目部署到Tomcat中运行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值