SpringBoot( 入门 + 启动 + 概述 + 整合 + 第三方依赖 )

SpringBoot

SpringBoot 简介

  • SpringBoot 设计目的是用来简化 Spring 应用的初始搭建以及开发过程

    • 注意:是简化而不是替代
    • Spring Framework 还是繁琐,尤其是配置部分
  • boot 更加简单是在于:起步依赖和自动配置

    • 依赖一个顶 spring 中的好几个 —— 依赖传递

引出

  1. 原先:创建工程,并在 pom.xml 配置文件中配置所依赖的坐标

  2. 编写 web3.0 的配置类

  3. 编写 SpringMVC 的配置类

    • 做到这是将工程的架子搭起来,要想被外界访问,最起码还需要提供一个 Controller 类,在该类中提供方法
  4. 编写 Controller 类

上面的程序开发,前三步都是在搭建环境,而且这三步基本都是固定的,SpringBoot 就是对这三步进行了简化

SpringBoot 快速入门

开发步骤

  • 创建新模块,选择Spring初始化,并配置模块相关基础信息
  • 选择当前模块需要使用的技术集
  • 开发控制器类
  • 运行自动生成的Application类
  • 展开:
  1. 创建新模块,选择 Spring Initializr,用来创建 SpringBoot 工程,JDK 用自己的版本并对 SpringBoot 工程进行相关的设置

    image-20230831210103707

    • 这种方式构建的 SpringBoot 工程其实也是 Maven 工程,而该方式只是一种快速构建的方式而已

    • 这里的 Package name 的值应该删去最后的 textboot ( 否则建好后就会多出来一个包 )

    • 注意:打包方式这里需要设置为 Jar

  2. 由于我们需要开发一个 web 程序,使用到了 SpringMVC 技术

    image-20230831210307250

    • jdk8 的话 SpringBoot 最好不选 3.0 以上的,因为可能只支持 jdk17 以上的
    • create 完成创建
  3. 完成创建的目录:

    image-20230831210901762

    • 除了 src 和 pom.xml 之外的其实暂时没有什么用处,这就已经是最基础的架子了
    • 会自动生成一个 Application 类,而该类一会再启动服务器时会用到
    • 在创建好的工程中不需要创建配置类
  4. 创建 Controller

@RestController
@RequestMapping("/books")
public class BookController {

    @GetMapping("/{id}")
    public String getById(@PathVariable Integer id){
        System.out.println("id ==> "+id);
        return "hello , spring boot!";
    }
}
  1. 启动服务器

    • 运行 SpringBoot 工程不需要使用本地的 Tomcat 和 插件,只运行项目包下的 Application 类,我们就可以在控制台看到信息

    • 运行:

      image-20230831211634638

    • 控制器显示:

      image-20230831211709129

      • 后面绿色信息可见,tomcat 已经启动了
  2. 进行测试

    • 输入网址可见:

      image-20230831212041718

    • 控制台最后一行也有打印:

      image-20230831212144758

  • 查看 Application 类和 pom.xml :
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!--  简化主因,指定了一个父工程,父工程中的东西在该工程中可以继承过来使用  -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.15</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>textboot</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <name>textboot</name>
    <description>textboot</description>

    <!--JDK 的版本-->
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!--该依赖就是我们在创建 SpringBoot 工程勾选的那个 Spring Web 产生的-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--这个是单元测试的依赖,我们现在没有进行单元测试,所以这个依赖现在可以没有-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!--这个插件是在打包时需要的,而这里暂时还没有用到-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <!--        第一次新建下面的会爆红,但不影响普通使用        -->
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!--        为解决红色就要加上版本号(和上面的parent版本一致即可)        -->
                <version>2.7.15</version>
            </plugin>
        </plugins>
    </build>

</project>
  • 代码之所以能简化,就是因为指定的父工程和 Spring Web 依赖实现的

对比

  • 坐标

    • Spring 程序中的坐标需要自己编写,而且坐标非常多

    • SpringBoot 程序中的坐标是我们在创建工程时进行勾选自动生成的

  • web3.0 配置类

    • Spring 程序需要自己编写这个配置类 ( 较复杂 )

    • SpringBoot 程序不需要自己手写

  • 配置类

    • Spring / SpringMVC 程序的配置类需要自己手写
    • SpringBoot 程序则不需要
  • 控制器因为是编写各自的需求,所以都要自己做

  • 注意:基于 idea 的 Spring Initializr 快速构建 SpringBoot 工程时需要联网

官网构建工程

  • 在入门案例中之所以能快速构建 SpringBoot 工程,是因为 Idea 使用了官网提供了快速构建 SpringBoot 工程的组件实现的
  • 那如何在官网进行工程构建:

进入 SpringBoot 官网

  • 官网地址:https://spring.io/projects/spring-boot

  • 选择最下面的 ( 快速构建一个项目 ):

    image-20230831213313015

  • 然后点击 Spring Initializr 超链接就会跳转到如下页面

    image-20230831213913797

  • 页面内容似曾相识,填写与前面的 idea 填写基本一致

  • 选择依赖,加上 Spring Web

    image-20230831214115336

    image-20230831214132914

  • 生成工程

    • 在页面的最下方点击 GENERATE CTRL + 回车按钮生成工程并下载到本地

      image-20230831214239340

    • 打开下载好的压缩包可以看到工程结构和使用 Idea 生成的一模一样,如下图

      image-20230831214438481

  • 通过上面官网的操作,我们知道 Idea 中快速构建 SpringBoot 工程其实就是使用的官网的快速构建组件,那以后即使没有 Idea 也可以使用官网的方式构建 SpringBoot 工程

SpringBoot 工程快速启动

问题导入

  • 以后我们和前端开发人员协同开发,而前端开发人员需要测试前端程序就需要后端开启服务器,这就受制于后端开发人员。为了摆脱这个受制,前端开发人员尝试着在自己电脑上安装 Tomcat 和 Idea,在自己电脑上启动后端程序,但这显然不现实
  • 我们后端可以将 SpringBoot 工程打成 jar 包给前端,该 jar 包运行不依赖于 Tomcat 和 Idea 这些工具也可以正常运行,只是这个 jar 包在运行过程中连接和我们自己程序相同的 Mysql 数据库即可
  • 那如何打包:

打包

  • 由于在构建 SpringBoot 工程时已经在 pom.xml 中配置了如下插件
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
  • 所以我们只需要使用 Maven 的 package 指令打包就会在 target 目录下生成对应的 Jar 包

    image-20230831215117565

  • 注意:该插件必须配置,不然打好的 jar 包也是有问题的

启动

  • 进入 jar 包所在位置

    image-20230831215206191

  • 就把此包发给前端人员

    image-20230831215302581

  • 前端在命令提示符 cmd 中输入如下命令

    java -jar textboot-0.0.1-SNAPSHOT.jar
    
    • jar 包的名称直接写一个 t 然后 tab 切换补全找到对的即可
  • 执行上述命令就可以看到 SpringBoot 运行的日志信息

    image-20230831221220161

    • 但可能出现错误:Error: Invalid or corrupt jarfile textboot-0.0.1-SNAPSHOT.jar
    • 本人删除重新打包就可了

SpringBoot 概述

  • SpringBoot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化 Spring 应用的初始搭建以及开发过程
    • 原始 Spring 缺点:
      • 配置繁琐
      • 依赖设置繁琐
    • SpringBoot 程序优点恰巧就是针对 Spring 的缺点
      • 自动配置:解决 Spring 程序配置繁琐的问题
      • 起步依赖:解决 Spring 程序依赖设置繁琐的问题
      • 辅助功能 ( 内置服务器,... ):启动 SpringBoot 程序时既没有使用本地的 tomcat 也没有使用 tomcat 插件,而是使用 SpringBoot 内置的服务器

起步依赖 - 探索父工程

  • 我们使用 Spring Initializr 方式创建的 Maven 工程的的 pom.xml 配置文件中自动生成了很多包含 starter 的依赖:
    • spring-boot-starter-parentspring-boot-starter-web
    • 这些依赖就是启动依赖

spring-boot-starter-parent

  • 从上面的文件中可以看到指定了一个父工程,我们进入到父工程,发现父工程中又指定了一个父工程 spring-boot-dependencies

  • 再进入到该父工程中,在该工程中我们可以看到配置内容结构为

    image-20230901193705334

  • 上图中的 properties 标签中定义了各个技术软件依赖的版本,避免了我们在使用不同软件技术时考虑版本的兼容问题

    • 即只要告诉了用的是 springBoot 哪个版本,剩下的就全部配好了
  • 在 properties 中我们找 servlet 和 mysql 的版本如下图 <servlet-api.version>4.0.1</servlet-api.version><mysql.version>8.0.33</mysql.version>

    • 这里只是版本的管理,实际没有用,引入是靠下面的 dependencyManagement
  • dependencyManagement 标签是进行依赖版本锁定

    • 由此就配置了一系列的版本和要用到的版本的依赖管理,但是并没有导入对应的依赖
  • 如果我们工程需要那个依赖只需要在 pom.xml 中引入依赖的 groupidartifactId 就好,而不需要定义 version

  • build 标签中也对插件的版本进行了锁定

spring-boot-starter-test

  • 点进去看找到 <dependencies>,此处就相当于一个 spring-boot-starter-test 替换了那百行的 <dependencies>

spring-boot-starter-web

  • web 开发用的起步依赖
  • 点开里面就有 spring-webspring-webmvc
  • 并且内置 spring-boot-starter-tomcat tomcat

结论

  • 以后需要使用技术,只需要引入该技术对应的起步依赖即可

  • starter

    • SpringBoot 中常见项目名称,定义了当前项目使用的所有项目坐标,以达到减少依赖配置的目的
  • parent

    • 所有 SpringBoot 项目要继承的项目,定义了若干个坐标版本号 ( 依赖管理,而非依赖 ),以达到减少依赖冲突的目的
    • 不同版本的 starter-parent 里的坐标版本差别很大,版本选择要合理而不是越新越好
  • 实际开发

    • 使用任意坐标时,仅书写 GAV 中的 G 和 A ,V 由 SpringBoot 提供
      • G:groupid

      • A:artifactId

      • V:version

  • 如发生坐标错误,再指定 version ( 要小心版本冲突 )

程序启动

  • 创建的每一个 SpringBoot 程序时都包含一个 xxxApplication 类,我们将这个类称作引导类,如:

    @SpringBootApplication
    public class TextbootApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(TextbootApplication.class, args);
        }
    
    }
    
  • 注意:

    • SpringBoot 在创建项目时,采用 jar 的打包方式
    • SpringBoot 的引导类是项目的入口,运行 main 方法就可以启动项目
  • tomcat 在前面的 spring-boot-starter-web 中已具备

  • 即此处的 spring-boot-starter-web 应该属于辅助功能,并非为了做程序用的

切换 web 服务器

  • 现在启动工程使用的是 tomcat 服务器,那能不能使用其他的如 jetty 服务器,这时候就要排除依赖,即使用 exclusion 标签排除 spring-boot-starter-web
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
    </exclusions>
</dependency>
  • 此时就无法运行引导类了,就可以加新的服务器:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
  • 接下来再次运行引导类,在日志信息中就可以看到使用的就是 jetty 服务器
    • Jetty 比 tomcat 更加轻量级、可扩展性更强

小结

  • 通过切换服务器,不难发现在使用 SpringBoot 换技术时只需要导入该技术的起步依赖即可

配置文件

配置文件格式

  • 我们现在启动服务器默认的端口号是 8080,访问路径可以书写为

    http://localhost:8080/books/1
    
  • 在线上环境还是将端口号改为 80,这样在访问的时候就可以不写端口号了,如下

    http://localhost/books/1
    
  • 而 SpringBoot 程序内该如何修改:

方式一: resources 文件夹里的 application.properties
server.port=81
方式二:resources 下新建文件 application.yml
server:
	port: 82
  • 输入 port 后有快捷格式

    image-20230901212242482

  • 不提示的话就

  • 注:port 后有空格

方式三:resources 下新建文件 application.yaml
server:
	port: 83
  • 只是扩展名不同,写法一样

  • 上述主要用 .yml 后缀的

  • 若是上面三个方式都有都存在,优先就是 application.properties 的配置

    • .properties > .yml > .yaml
  • 注意:SpringBoot 程序的配置文件名必须是 application,只是后缀名不同而已

  • port 不提示的话就:

    • 手动加入配置文件

      image-20230901212639374

      image-20230901212813675

    • 列入配置文件内就有提示了

注意
  • SpringBoot 核心配置文件名为 application

  • SpringBoot 内置属性过多,且所有属性集中在一起修改,在使用时,通过提示键 + 关键字修改属性

  • 例如要设置日志的级别时,可以在配置文件中书写 logging,就会提示出来配置内容

    logging:
      level:
        root: info
    
    • 同样此处 root 后有空格

yaml格式

  • YAML ( YAML Ain't Markup Language ),一种数据序列化格式

  • 这种格式的配置文件在近些年已经占有主导地位,那么这种配置文件和前期使用的配置文件是有一些优势的,先看之前使用的配置文件 ( 想要在配置文件中读取数据信息 )

    • 最开始使用的 xml:

      <enterprise>
          <name>itcast</name>
          <age>16</age>
          <tel>4006184000</tel>
      </enterprise>
      
    • properties 类型的配置文件:

      enterprise.name=itcast
      enterprise.age=16
      enterprise.tel=4006184000
      
    • yaml 类型的配置文件:

      enterprise:
      	name: itcast
      	age: 16
      	tel: 4006184000
      
  • 优点

    • 容易阅读
      • yaml 类型的配置文件比 xml 类型的配置文件更容易阅读,结构更加清晰
  • 容易与脚本语言交互

    • 以数据为核心,重数据轻格式
      • yaml 更注重数据,而 xml 更注重格式
  • YAML 文件扩展名

    • .yml (主流 )

    • .yaml

  • 上面两种后缀名都可以,以后使用更多的还是 yml

语法规则
  • 大小写敏感

  • 属性层级关系使用多行描述,每行结尾使用冒号结束

  • 使用缩进表示层级关系,同层级左侧对齐,只允许使用空格

    • 不允许使用 Tab 键
    • 空格的个数并不重要,只要保证同层级的左侧对齐即可
  • 属性值前面添加空格

    • 属性名与属性值之间使用冒号 + 空格作为分隔

    • 核心规则!:数据前面要加空格与冒号隔开

  • # 井号表示注释

  • 数组数据在数据书写位置的下方使用减号作为数据开始符号,每行书写一个数据,减号与数据间空格分隔,例如:

    enterprise:
      name: qst
      age: 23
      tel: 123456789
      subject:
        - Java
        - 前端
        - 大数据
    

yaml 配置文件数据读取

环境准备
  • 新创建一个名为 springboot_03_read_data 的 SpringBoot 工程

  • 在 com.qst.controller 包写创建名为 BookController 的控制器,内容如下:

@RestController
@RequestMapping("/books")
public class BookController {

    @GetMapping("/{id}")
    public String getById(@PathVariable Integer id){
        System.out.println("id ==> "+id);
        return "hello , spring boot!";
    }
}
  • 在 com.qst.domain 包下创建一个名为 Enterprise 的实体类等会用来封装数据,内容如下:
public class Enterprise {
    private String name;
    private int age;
    private String tel;
    private String[] subject;
    
    //setter and getter
    //toString
}
  • 在 resources 下创建一个名为 application.yml 的配置文件,里面配置了不同的数据,内容如下:
lesson: SpringBoot

server:
  port: 80

enterprise:
  name: qst
  age: 23
  tel: 123456789
  subject:
    - Java
    - 前端
    - 大数据
读取配置数据
  • 主要用第三种方式
方式一:使用 @Value 注解
  • 使用 @Value("表达式") 注解可以从配合文件中读取数据,注解中用于读取属性名引用方式是:${一级属性名.二级属性名……}

  • 我们可以在 BookController 中使用 @Value 注解读取配合文件数据 ( 直接用名称 ),如下

@RestController
@RequestMapping("/books")
public class BookController {
    
//   直接写其名称就可读取:    
    @Value("${lesson}")
    private String lesson;
    @Value("${server.port}")
    private Integer port;
    @Value("${enterprise.subject[0]}")
    private String subject_0;

    @GetMapping("/{id}")
    public String getById(@PathVariable Integer id){
        System.out.println(lesson);
        System.out.println(port);
        System.out.println(subject_00);
        return "hello , spring boot!";
    }
}
方式二:Environment 对象
  • 上面方式读取到的数据特别零散,所有还可以使用 @Autowired 注解注入 Environment 对象的方式读取数据

    • 这种方式 SpringBoot 会将配置文件中所有的数据封装到 Environment 对象中,如果需要使用哪个数据只需要通过调用 Environment 对象的 getProperty(String name) 方法获取,具体代码如下:

      @RestController
      @RequestMapping("/books")
      public class BookController {
      
          // 注解自动装配给值,env就可以加载所有的环境信息
          @Autowired
          private Environment env;
          
          @GetMapping("/{id}")
          public String getById(@PathVariable Integer id){
              // 使用:
              System.out.println(env.getProperty("lesson"));
              System.out.println(env.getProperty("enterprise.name"));
              System.out.println(env.getProperty("enterprise.subject[0]"));
              return "hello , spring boot!";
          }
      }
      
  • 这种方式,框架内容大量数据,开发中很少使用

方式三:自定义对象
  • SpringBoot 还提供了将配置文件中的数据封装到我们自定义的实体类对象中的方式,具体操作如下:
  • 将环境准备中的实体类 Enterprise 加注解成 bean 的创建交给 Spring 管理

    • 添加 @Component 注解
  • 使用 @ConfigurationProperties 注解表示加载配置文件

    • 在该注解中也可以使用 prefix 属性指定只加载指定前缀的数据
  • BookController 中进行注入

  1. Enterprise 实体类内容如下:
@Component
// 此处的enterprise就是application.yml中的,内容与下面属性一一对应
// 也可以enterprise.xxx 即从下一级的一个开始加载
@ConfigurationProperties(prefix = "enterprise")
public class Enterprise {
    private String name;
    private int age;
    private String tel;
    private String[] subject;

    //get、set、tostring
}
  1. BookController 自动装配:
@RestController
@RequestMapping("/books")
public class BookController {
    
    // 还是自动装配
    @Autowired
    private Enterprise enterprise;

    @GetMapping("/{id}")
    public String getById(@PathVariable Integer id){
        System.out.println(enterprise.getName());
        System.out.println(enterprise.getAge());
        System.out.println(enterprise.getSubject());
        System.out.println(enterprise.getTel());
        System.out.println(enterprise.getSubject()[0]);
        return "hello , spring boot!";
    }
}
  • 使用第三种方式,在实体类上有警告提示,在 pom.xml 中添加如下依赖即可解决这个警告提示

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

多环境配置

  • 以后在工作中,对于开发环境、测试环境、生产环境的配置肯定都不相同,比如我们开发阶段会在自己的电脑上安装 mysql ,连接自己电脑上的 mysql 即可,但是项目开发完毕后要上线就需要改配置,将环境的配置改为线上环境的

    • 即三个环境,三个 url、user、password
  • 来回的修改配置会很麻烦,而 SpringBoot 给开发者提供了多环境的快捷配置,需要切换环境时只需要改一个配置即可。不同类型的配置文件多环境开发的配置都不相同,接下来对不同类型的配置文件进行说明

yaml文件
  • profile 快捷选择

  • 在 application.yml 中使用 --- 三个横线来分割不同的配置,内容如下

    • 前两行:设置xx环境
    • 后两行:xx环境具体参数设定
#开发
spring:
  profiles: dev #给开发环境起的名字
server:
  port: 80
  
---
#生产
spring:
  profiles: pro #给生产环境起的名字
server:
  port: 81
---
#测试
spring:
  profiles: test #给测试环境起的名字
server:
  port: 82
---
  • 上面配置中 spring.profiles 是用来给不同的配置起名字的 ( 自定义命名 )
    • 而如何告知 SpringBoot 使用哪段配置,可以使用如下配置来启用一段配置
#设置启用的环境
spring:
  profiles:
    active: dev  #表示使用的是开发环境的配置
  • 综上所述,application.yml 配置文件内容如下:
#设置启用的环境
spring:
  profiles:
    active: dev

---
#开发
spring:
  profiles: dev
server:
  port: 80
---
#生产
spring:
  profiles: pro
server:
  port: 81
---
#测试
spring:
  profiles: test
server:
  port: 82
---
  • 注意:在上面配置中给不同配置起名字的 spring.profiles 配置项已经过时,即有的用删除线划掉了,而最新用来起名字的配置项是:
#开发
spring:
  config:
    activate:
      on-profile: dev

#替换了以下部分
spring:
  profiles: dev
properties文件 ( 了解 )
  • properties 类型的配置文件配置多环境需要定义不同的配置文件

    • application-dev.properties 是开发环境的配置文件,我们在该文件中配置端口号为 80

      server.port=80
      
    • application-test.properties 是测试环境的配置文件。我们在该文件中配置端口号为 81

      server.port=81
      
    • application-pro.properties 是生产环境的配置文件。我们在该文件中配置端口号为 82

      server.port=82
      
  • SpringBoot 只会默认加载名为 application.properties 的配置文件,所以需要在 application.properties 配置文件中设置启用哪个配置文件,配置如下:

spring.profiles.active=pro
  • active=上述三种配置文件名横线后面的值 ( dev、test、pro )
    • 即启动文件名固定,想启动哪个环境就再新建对应文件
命令行启动参数设置
  • 使用 SpringBoot 开发的程序以后都是打成 jar 包,通过 java -jar xxx.jar 的方式启动服务的,那么就存在一个问题:配置文件打包到 jar 包中了,如何切换其中环境?

    • 其实测试方在修改环境时是用命令行来操作的
  • jar 打包前最好 clean 下以防万一再 package 打包,但若是有中文的话 ( 注解也是 ),就要改配置为 UTF-8

    image-20230902141126713

    • 下面这个也建议改为 UTF-8

      image-20230902141301429

  • jar 包其实就是一个压缩包,可以解压缩,然后修改配置,最后再打成 jar 包,但这种方式显然有点麻烦,而 SpringBoot 提供了在运行 jar 时设置开启指定的环境的方式

    • cmd 命令行打开,输入指令不变,后面再加上 -- 配置,如下:

      java –jar xxx.jar –-spring.profiles.active=test
      
    • 同用这种方式临时修改端口号,可以通过如下方式:

      java –jar xxx.jar –-server.port=88
      
    • 当然也可以同时设置多个配置,比如即指定启用哪个环境配置,又临时指定端口,如下

      java –jar springboot.jar –-server.port=88 –-spring.profiles.active=test
      
    • ctrl + c:停止运行

  • 大家进行测试后就会发现命令行设置的端口号优先级高 ( 也就是使用的是命令行设置的端口号 ),配置的优先级这点其实 SpringBoot 官网已经进行了说明

多环境开发控制
  • 若是 maven 配置了多环节开发,boot 中也配置了多环境,那这两个究竟是启动了哪一个?
    • maven 的 pom 里:<profiles> 里设置了多个 <profile> 多个环境
    • boot 里同上 yaml 文件所讲:多个环境 --- 隔开
  • 注意:boot 工程最终是在服务器上启动,用命令行 java -jar ... 启动,即最终启动的是打包好的 jar 包,而 jar 包是 maven 的 package 指令帮助做的,所以 maven 里的占主导作用 ( boot 只是个工具,为辅 )
    • boot 的 yaml 文件中改为 active:${profile.active}
    • pom 里就要加 <profile.active> 并加入配置解析资源文件的插件

配置文件分类 ( 优先级 )

  • 临时属性太多,由于测试环境和开发环境的很多配置都不相同,所以每次测试人员在运行我们的工程时需要临时修改很多配置,如下:

    java –jar springboot.jar –-spring.profiles.active=test --server.port=85 --server.servlet.context-path=/heima --server.tomcat.connection-timeout=-1 …… …… …… …… ……
    
    • 不仅多还容易写错
  • 针对这种情况,SpringBoot 定义了配置文件不同的放置的位置;而放在不同位置的优先级时不同的

  • SpringBoot 中 4 级配置文件放置位置:

    • 1 级:classpath:application.yml

    • 2 级:classpath:config/application.yml

    • 3 级:file :application.yml

    • 4 级:file :config/application.yml

      • 级别越高优先级越高
      • 最高的四级即表示,在 jar 包所在的目录下新建一个 config 目录,将一个配置好的 application.yml 文件复制到此目录下,则此文件中的配置优先级最高,运行 jar 包时的配置端口就是此 application 里所写的 ( 覆盖了其地方写的配置 )
      • 上述四级在 2.4.6 和 2.5.0 的版本 ( 之后的其他版本不知 ) 有一个 bug 就是若是用四级配置文件,就需要在 config 下再建一个随意命名的文件夹 ( 空着即可 )
  • 这样的好处就是,在自己编写开发时,只需要好好写自己的 resources 下的配置文件即可,在打包前再将测试人员所需的配置文件写进优先级高的地方即可

  • 即 3、4 级是为了开发服务的,1、2 级是为了上线服务的

SpringBoot 整合 junit

  • Spring 整合 junit:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {
    
    @Autowired
    private BookService bookService;
    
    @Test
    public void testSave(){
        bookService.save();
    }
}
  • 使用 @RunWith 注解指定运行器,使用 @ContextConfiguration 注解来指定配置类或者配置文件,括号内指定大多都一样,所以 boot 就简化了

环境准备

  • com.qst.service 下创建 BookService 接口:

    public interface BookService {
        public void save();
    }
    
  • 在 com.qst.service.impl 包下创建一个 BookServiceImpl 类,使其实现 BookService 接口:

    @Service
    public class BookServiceImpl implements BookService {
        @Override
        public void save() {
            System.out.println("book service is running ...");
        }
    }
    

编写测试类

  • 在 test / java 下创建 com.qst 包,在该包下创建测试类,将 BookService 注入到该测试类中:

    // 默认加注解:
    @SpringBootTest
    class SpringbootTestApplicationTests {
    
        @Autowired
        private BookService bookService;
    
        @Test
        public void save() {
            bookService.save();
        }
    }
    
    • boot 帮助加载了 spring 时的两个注解 ( 包括配置文件 ),所以这里就不用再写了
      • 引导类就可以把
  • 注意:这里的引导类所在包必须是测试类所在包及其子包

  • 例如:

    • 引导类所在包是 com.qst
    • 测试类所在包就是 com.qst

SpringBoot 整合 mybatis

  • 没有 SpringBoot 整合 Spring、SpringMVC,本质一样,只不过简化了很多手动配置

回顾 Spring 整合 Mybatis

  • Spring 整合 Mybatis 需要定义很多配置类
  • SpringConfig 配置类

    • 导入 JdbcConfig 配置类

    • 导入 MybatisConfig 配置类

      @Configuration
      @ComponentScan("com.qst")
      @PropertySource("classpath:jdbc.properties")
      // 导入两个配置文件:
      @Import({JdbcConfig.class,MyBatisConfig.class})
      public class SpringConfig {
      }
      
  • JdbcConfig 配置类

    • 定义数据源 ( 加载 properties 配置项:driver、url、username、password )

      public class JdbcConfig {
          @Value("${jdbc.driver}")
          private String driver;
          @Value("${jdbc.url}")
          private String url;
          @Value("${jdbc.username}")
          private String userName;
          @Value("${jdbc.password}")
          private String password;
      
          @Bean
          public DataSource getDataSource(){
              DruidDataSource ds = new DruidDataSource();
              ds.setDriverClassName(driver);
              ds.setUrl(url);
              ds.setUsername(userName);
              ds.setPassword(password);
              return ds;
          }
      }
      
  • MybatisConfig 配置类

    • 定义 SqlSessionFactoryBean

    • 定义映射配置

      @Bean
      public MapperScannerConfigurer getMapperScannerConfigurer(){
          MapperScannerConfigurer msc = new MapperScannerConfigurer();
          msc.setBasePackage("com.qst.dao");
          return msc;
      }
      
      @Bean
      public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource dataSource){
          SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
          ssfb.setTypeAliasesPackage("com.qst.domain");
          ssfb.setDataSource(dataSource);
          return ssfb;
      }
      

SpringBoot 整合

  • 上述大多数都不需要再写了

创建模块

  • 创建新模块,选择 Spring Initializr,并配置模块相关基础信息

  • 选择当前模块需要使用的技术集 ( MyBatis、MySQL )

    image-20230902171204252

    • 创建后会发现都给配置了

      image-20230902172000606

定义实体类

  • 在 com.qst.domain 包下定义实体类 Book,内容如下
public class Book {
    private Integer id;
    private String name;
    private String type;
    private String description;
    
    //setter and getter   
    //toString
}

定义 dao 接口

  • 在 com.qst.dao 包下定义 BookDao 接口,内容如下
public interface BookDao {
    @Select("select * from tbl_book where id = #{id}")
    public Book getById(Integer id);
}

定义测试类

在 test / java 下定义包 com.qst,在该包下测试类,内容如下

@SpringBootTest
class Springboot08MybatisApplicationTests {

	@Autowired
	private BookDao bookDao;

	@Test
	void testGetById() {
		Book book = bookDao.getById(1);
		System.out.println(book);
	}
}
  • bookDao 报错的话就:

    image-20230902175220878

    • 把 error 改成 warning ( 属于环境的问题 )

      image-20230902175304877

编写配置

  • 在 application.yml 配置文件中配置如下内容
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost/enterprise
    username: root
    password: 123456

测试

  • 运行测试方法,我们会看到如下错误信息

    • No qualifying bean of type 'com.qst.dao.BookDao' available: expected at least 1 bean which qualifies as autowire candidate.

    • 本来是需要一个对象,即自动代理这个 BookDao 接口,Mybatis 会扫描接口并创建接口的代码对象交给 Spring 管理,但是现在并没有告诉 Mybatis 哪个是 dao 接口

    • SpringBoot 的话,这里想要自动代理就在接口上加一个注解 @Mapper 即可:

      @Mapper
      public interface BookDao {
          @Select("select * from staff_info where id = #{id}")
          public Book getById(Integer id);
      }
      
    • SpringBoot 版本低于 2.4.3 ( 不含 ),Mysql 驱动版本大于 8.0 时,需要在 url 连接串中配置时区 jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC,或在 MySQL 数据库端配置时区解决此问题

使用Druid数据源

  • 现在并没有指定数据源,SpringBoot 有默认的数据源,可以指定使用 Druid 数据源,按照以下步骤实现
  • 导入 Druid 依赖

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>
    
  • application.yml 配置文件配置,通过 spring.datasource.type 来配置使用什么数据源,其内容可以改进为

    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/enterprise
        username: root
        password: 123456
        type: com.alibaba.druid.pool.DruidDataSource
    

案例

  • 整合 SSM 的项目为 SpringBoot
  1. pom.xml

    • 配置起步依赖,必要的资源坐标 ( druid )
  2. application.yml

    • 设置数据源、端口等
  3. 配置类

    • 全部删除
  4. dao

    • 设置 @Mapper
  5. 测试类

  6. 页面

    • 放置在 resources 目录下的 static 目录中

创建工程

  • 创建 SpringBoot 工程,在创建工程时需要勾选 webmysqlmybatis,命名:springboot-ssm

  • 由于我们工程中使用到了 Druid ,所以需要导入 Druid 的坐标

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>
    

代码拷贝

  • 将 SpringMVC 工程中的 java 代码及测试代码连同包拷贝到 springboot-ssm 工程,按照下图进行拷贝

  • 需要修改的内容如下:

    • SpringMVC config 包下的是配置类,而 SpringBoot 工程不需要这些配置类,所以这些可以直接删除

      • JdbcConfig 转换成配置,MyBatisconfig ...... 全拿掉
    • dao 包下的接口上在拷贝到 springboot-ssm 工程中需要在接口中添加 @Mapper 注解

    • BookServiceTest 测试需要改成 SpringBoot 整合 junit

      @SpringBootTest
      public class BookServiceTest {
      
          @Autowired
          private BookService bookService;
      
          @Test
          public void testGetById(){
              Book book = bookService.getById(2);
              System.out.println(book);
          }
      
          @Test
          public void testGetAll(){
              List<Book> all = bookService.getAll();
              System.out.println(all);
          }
      }
      
      • 需要随时看的地方可以 <!-- TODO 添加必要的依赖坐标 --> 加上 TODO 说明,以便于在 idea 下方迅速查看

配置文件

  • application.yml 配置文件中需要配置如下内容

    • 服务的端口号

    • 连接数据库的信息

    • 数据源

server:
  port: 80

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/enterprise
#    url: jdbc:mysql://localhost:3306/enterprise?servierTimezone=UTC
    username: root
    password: 123456
    type: com.alibaba.druid.pool.DruidDataSource

静态资源

  • 在 SpringBoot 程序中是没有 webapp 目录的,其静态资源需要放在 resources 下的 static 文件夹下的 css、js、pages 等等里,在 static 里新建一个 index.html 为主页 ( 在里面指定主页即可 ):

    <script>
        document.location.href="pages/xxxx.html"
    </script>
    

导入第三方依赖

  • 导入第三方模块依赖后,不能使用:因为没有扫描到
  • 虽然 @SpringBootApplication 内有扫描功能,但只能扫描当前包和子包 ( 此模块中 java 下的项目内的包 )

方法一:

  • @ComponentScan 组件扫描

    @ComponentScan({"com.enterprise", "com.qst"})
    @SpringBootApplication
    public class EnterpriseMsBApplication {
    }
    
    • 第三方包多的话性能并不高

方法二:

  • @Import 导入,使用此注解导入的类会被 spring 加载到 IOC 容器中,导入形式主要有以下几种:

    • 导入普通类,这样的话不管此类加不加 @Component 注解都可 ( 因为直接指定了 ),如:@Import({TokenParser.class})

    • 导入配置类,形式同上导入普通类的方式,进 IOC 内被管理的就是此配置类下的 @Bean

    • 导入 ImportSelector 接口实现类

      • 有一个类:

        public class MyImportSelector implements ImportSelector { // 实现此类
            public String[] selectImports(AnnotationMetadata importingClassMetadata) {
                return new String[]{"com.example.类名"}; // 想要加载进IOC的类名都写进来即可
            }
        }
        
      • 然后同上 @Import({MyImportSelector.class})

    • 推荐:第三方依赖里配好 EnableXxxx 类作为,封装 @Import 注解

      • 第三方里的 EnableXxxx 接口中:

        @Target(ElementType.TYPE)
        @Retention(RetentionPolicy.RUNTIME)
        // 上述为元注解
        
        @Import(MyImportSelector.class) // 此处的MyImportSelector类就是上一种方法的类
        public @interface EnableHeaderConfig {
        }
        
      • 这样想要使用此第三方依赖导入 Bean 的话就直接加上 @EnableHeaderConfig 注解即可

@SpringBootApplication

  • 该注解标识在 SpringBoot 工程引导类上,是 SpringBoot 中最最最重要的注解
  • 该注解由三个部分组成:
    • @SpringBootConfiguration:该注解与 @Configuration 注解作用相同,用来声明当前也是一个配置类
    • @ComponentScan:组件扫描,默认扫描当前引导类所在包及其子包
    • @EnableAutoConfiguration:SpringBoot 实现自动化配置的核心注解
      • 内含 @Import
posted @ 2023-09-19 22:03  朱呀朱~  阅读(299)  评论(0编辑  收藏  举报