Spring Boot3入门

前期回顾

  • Git和svn的区别
  • git常用的命令

git init

git clone -b dev

git add

git commit -m "xxxx"

git push

git pull

git status

git branch

git checkout -b

  • Git分支的作用

任务

springboot的底层本质还是ssm。只是把一些繁琐的配置文件用配置类代替了,Tomcat内嵌,等先就这么理解。

spring核心基础

主要是把ioc和aop之前是在applicationContext.xml里写的,改到写配置类的形式

https://www.jf3q.com/article/detail/4130

springmvc核心基础

把之前在springmvc.xm配置的内容也改成配置类的形式

https://www.jf3q.com/article/detail/4169

springboot优点

  • 快速创建独立的 Spring 企业级应用程序;
  • 直接嵌入 Tomcat,Jetty 或 Undertow,无需部署 WAR 文件;
  • 提供"初始"的 POM 文件内容,以简化 Maven 配置;
  • 尽可能自动配置 Spring;
  • 提供生产环境的特征指标、健康检查和外部配置;
  • 对主流开发框架的无配置集成;
  • 提供运行时的应用监控;
  • 极大地提高了开发、部署效率

Spring Boot 3.0的新特性

  • 1.Java 版本升级 :
    • 从 Java 的版本从 Java 8 提升到了 Java 17。
  • 2.从 Java EE APIs 到 Jakarta EE
    • 从 Spring Boot 3.0 开始,所有的 Java EE API 都需要迁移到 Jakarta EE 上来。大部分用户需要修改import 相关 API 的时候,要用Jakarta 替Javax 。
  • 3.移除过时技术

移除了下面这些技术的支持:

  • Apache ActiveMQ
  • Atomikos
  • EhCache 2
  • Hazelcast 3
  • 4.依赖升级
  • 5.其他改变

Spring Boot 3.0 将删除所有不推荐的代码,不再支持传统模式配置,Spring Boot 3.0 不再提供传统模式支持,不应该再有这个设置:spring.config.use-legacy-processing。推荐使用 PathPatternParser 而不是 AntPathMatcher

搭建Spring Boot 3.0 开发环境

  • 安装 JDK17 及以上的版本。
  • 安装 IDEA 集成开发环境(建议 2021 及以后版本)
  • 安装 MAVEN 项目管理工具(建议 3.8.4 以上版本)maven 安装好后,还需要在IDEA 中进行配置。
  • 安装 mysql 数据库(建议 8.0 版本)
  • 为方便测试,建议安装 Postman。

通过maven的方式创建

spring initializr

xml 复制代码
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.0.0</version>
  </parent>
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
java 复制代码
@SpringBootApplication
public class App
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class);

    }
}

通过idea提供的自动化创建方式


springboot原理

父工程parent

Springboot 使用 parent 进行依赖管理,Spring Boot 项目创建完成后,其 pom.xml 中有一个标签,标签中定义了 spring-boot-starter-parent 依赖,这是所有 Spring Boot 项目的父项目(又称父工程或父依赖),代码如下所示:

xml 复制代码
<parent> 
  <groupId>org.springframework.boot</groupId> 
  <artifactId>spring-boot-starter-parent</artifactId> 
  <version>3.0.0-SNAPSHOT</version> 
  <relativePath/> 
</parent>

spring-boot-starter-parent 父项目用来做依赖管理,托管子项目,其作用包括:

  • 标识该项目是一个 Spring Boot 项目。
  • 指定其字符集为 UTF-8。
  • 维护各项技术的版本号。

按住 Ctrl 键点击这个依赖链接,进入其详情,可以发现其中又出现了另一个标签 , 表 明 它 还 有 一 个 父 依 赖 , 依 赖 名 称 是 spring-boot-dependencies , 这 是spring-boot-starter-parent 的父项目,定义着所有依赖的版本和管理,按住 Ctrl 键点击该依赖的链接,进入其详情,可以发现其中的节点定义了一大堆依赖的版本号。

并且节点,即依赖管理,也定义了一大堆依赖引用了上述版本号变量

Spring-boot-dependencies 存放着 Spring Boot 的核心依赖,管理 Spring Boot 应用里面的所有依赖版本,这样,将来 Spring Boot 项目中若引用了这些依赖,将无须指定版本号,无须再为使用什么版本而伤脑筋,更重要的是,这些依赖的版本都是 Spring Boot 精挑细选出来的组合,不会出现版本冲突问题,否则所有依赖都要自己去找版本很容易出现依赖部冲突的问题。注意,仍然有一些依赖没有被 Spring Boot 官方收录进来,没有收录进来的依赖仍然要写版本号。 不同版本的 Spring Boot 它选择的各种依赖的版本组合不同,一般来说,Spring Boot 的版本较高,它选用的各种常用依赖的版本也相应较高。

场景启动器

Spring Boot 还提供了各种各样的 starter,又称为场景使用器,Spring Boot 将常用的功能场景抽取出来,做成一个个 starter(启动器),以快速实现特定功能。每一个场景启动器又集成了若干个依赖,这样导入了一个场景启动器就想当于导入了若它所集成的若干个依赖,无须用户一个个导入,如本章第一个 Spring Boot 项目中导入了 spring-boot-starter-web,这个是用于 Web 功能的场景启动器,有了它就可以进行 Spring MVC 开发,因为它内部集成了多个 Web 开发所需要的依赖,下面来探究一下该场景启动器。

首先在 pom.xml 观察一下 spring-boot-starter-web 依赖,发现该依赖并没有提供版本号,在 spring-boot-dependencies 查找关键字 starter-web,发现其中已提供了版本号,这就是使用进行依赖版本管理的好处之一。

里 面 已 经 包 含 了 Spring MVC 开 发 所 需 要 所 有 依 赖 , 如 spring-webmvc ,spring-boot-starter-json,以及所需的 tomcat 容器,从而可以知道,一个场景启动器就是集成了完成某个特定功能所需的所有依赖,大大减少了开发人员一个个自动导入依赖的麻烦,再加上的版本管理,可以让开发人员轻松就创建好某种特定目的的开发环境。

启动类

Spring Boot 的启动类是程序的执行入口,运行启动类的 main 方法就可以启动项目, 启动类将会初始化 Spring 容器,扫描启动类所在的包,加载各种 Bean。点击启动类中的@SpringBootApplication 链接,可以发现该注解实际上是以下三个主要注解组合而成:

java 复制代码
@SpringBootConfiguration 
@EnableAutoConfiguration 
@ComponentScan

其中@SpringBootConfiguration 注解表示当前类是个配置类,@EnableAutoConfiguration 注解表示加载自动配置类,@ComponentScan 注解表示扫描当前类所在包及其子包下的所有组件,这也说明了为什么 Spring Boot 项目的各种类必须要创建到跟启动类同一个包或其子包中,否则无法扫描到,不能加载到 Spring 容器中。

启 动 类 的 main 方 法 中 的 SpringApplication 的 run 方 法 返 回 ConfigurableApplicationContext 类型的对象,其实它就是大家熟悉的Spring 容器,这里来做 个测试,修改代码,尝试在 Spring 容器中查找是否存在刚才创建的 HelloController 类型的 Bean。代码如下:

这证明了启动类运行后,HelloController 类的 Bean 就被成功的加载到了 Spring 容器中。还可以使用循环遍历出初始化完成后添加到项目中的所有 Bean 来,修改代码如下。

控制台中将出现很多的 Bean 的名称。

Springboot 启动流程

(1)初始化阶段:此阶段会创建一个 SpringApplication 实例,并设置实例的资源、环境、监听器、构造器。

(2)应用启动阶段:此阶段会创建监听器模块、创建并设置环境实例、设置 banner、构建应用上下文对象、 应用启动,加载自动化配置信息

(3)自动化配置阶段 :@EnableAutoConfiguration 注解导入了一个 AutoConfigurationImportSelector.class 实例, 该类会扫描类路径上的 jar 包,如果在 META-INF/下有 spring.factories 文件,它就会通过 SpringFactoriesLoader.loadFactoryNames 方法加载这个文件中的全路径类名到 spring 容器中。 loadFactoryNames()需要类加载器和全路径类名才能加载一个类。关于自动配置的原理,第 8 章还会专门介绍。

web服务器

Spring Boot 中可以使用 Tomcat、Jetty 及 Undertow 三种 Web 服务器。其中 Tomcat 服务器应用最广,Jetty 相对轻量级,Undertow 负载性稍强。Spring Boot 默认使用了内嵌的 Tomcat 服务器。 在 pom.xml 中点击 spring-boot-starter-web 依赖的链接,可以看到该场景启动器已经包含了 spring-boot-starter-tomcat 依赖,显然这也是个场景启动器,点击该依赖的链接,可以发现有更多的 Tomcat 相关的依赖,其中 tomcat-embed-core 依赖表明使用了内嵌的 Tomcat 服务器,其原理就是将 Tomcat 服务器当对象运行,并交给 Spring 容器管理。

要想切换成 Tomcat 以外的其他服务器,如 Jetty,做法是先把 Tomcat 依赖从 spring-boot-starter-web 依赖中排除 ,这 需 要 在 spring-boot-starter-web 依赖中添加节点,具体如下代码所示:

xml 复制代码
<dependency> 
  <groupId>org.springframework.boot</groupId> 
  <artifactId>spring-boot-starter-web</artifactId> 
  <exclusions> 
    <exclusion> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-tomcat</artifactId> 
    </exclusion>  
  </exclusions> 
</dependency>  

这样 Tomcat 依赖就被排除掉了,然后,现再在 pom.xml 中添加 Jetty 的依赖,代码如 下所示:

xml 复制代码
<dependency> 
   <groupId>org.springframework.boot</groupId>  
   <artifactId>spring-boot-starter-jetty</artifactId>  
</dependency>

会报错:NoClassDefFoundError: jakarta/servlet/http/HttpSessionContext

springboot版本从2.x升级到3.x就会出现这种问题,解决方法,加上如下依赖

xml 复制代码
 <dependency>
      <groupId>jakarta.servlet</groupId>
      <artifactId>jakarta.servlet-api</artifactId>
      <version>5.0.0</version>
  </dependency>

springboot配置

Spring Boot 提供了很多应用的自动配置,也可以自定义配置修改(覆盖)默认配置值。 如默认提供的 Tomcat 端口号是 8080,但可以在 resource 路径下的 application.propertis 配置 文件中添加代码server.port=80 修改端口号为 80,重新启动项目,即可发现项目只可以用 80 端口访问了。

常用配置

除了配置端口号外,还可以配置更多的东西,比如如果要修改应用的访问上下文,可以 在 application.properties 文件中这样配置:server.servlet.context-path=/goods,这样访问项目资源时,其 url 除了 http://localhost:8080 外,还要上 goods,即 http://localhost:8080/goods 才能访问, 如果想调整日志的级别可以这样配置:logging.level.root=debug,意思是将日志 级别调整为 debug 级别,这样初始化时所有的 Bean 都将显示到控制台,如果设置为 error, 则只有错误时才显示日志,默认其值是 info,即是我们正常启动 Spring Boot 时看到的控制台 信息。当然还有更多的配置,比如修改数据源配置,修改缓存的配置,JSON 配置等等。

更 多 配 置 可 以 查 看 Spring 官 网 : https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#appendix.application-properties

左侧显示大类,右侧是其具体的各种配置项名称、描述与默认值。

配置文件类型

除了上述的 application.properties 文件进行配置外,还可以使用application.yml 文件进 行配置,以及 application.yaml 文件进行配置,这三种配置文件也可同时存在,如果里面的 配置项有冲突,则按如下优先级 :

application.properties>application.yml> application.yaml

优先级高的相同配置将覆盖优先级低的相同配置项,如果没有冲突,则三个文件中的所有配置 项均同时起作用。此外注意配置项起作用的前提条件是相关的依赖要导入,否则会报错。

三种配置文件同时出现在 resource 路径下,application.properties 中配置 server.port=8081, application.yml 中配置 server.port=8082,application.yaml 中配置 server.port=8083,启动项目,观察控制台中的启动端口号,可以发现是 8081,将 application.properties 文件删除,再次启动项目,可以发现端口变成了 8082。

yaml配置方式

YAML 是最近非常流行的一种数据序列化格式,跟 xml 方式比较,xml 格式太突显,数据不突显,而 yaml 配置方式充分突显了数据,弱化了格式,跟 properies 方式相比,消除了大量的重复,大大减少了代码量,且层次化更加清晰,容易阅读,容易与脚本语言交互。YAML 配置文件可以用.yaml 后缀,也 可用.yml 后缀,一般使用.yml 后缀。

  • 如果是配置单一的属性与值,则属性名称后面使用冒号,冒号后面要先有一个空格,空格后面是属性对应的值,
  • 如果是多层级的属性,则冒号后面留空,然后换行,并且换行后要 缩进若干个空格再配置下一层级的属性,缩进的空格数不限,但不能用 Tab 键进行缩进,
  • 如果有还有下一级则类推,最后一层级的属性接冒号,冒号后面先有一个空格然后是值,
  • 如果是同一层级的属性,则要有相同的缩进,即左侧竖向要对齐。同一层级不允许出现同名的属 性。YAML 用符号#进行注释。

properties 配置与 YAML 配置同一相同事项的对比:

properties 复制代码
server.servlet.context-path=/good
server.port=80
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/brand
yaml 复制代码
server:
  port: 82
  servlet:
    context-path: /good
spring:
  datasource:
    password: 123456
    username: root
    url: jdbc:mysql://localhost:3306/brand

YAML 配置单一属性示例:

yaml 复制代码
username: xiaoming
password: 123456
mobilephone: 15336574540

YAML 配置二级配置示例:

yaml 复制代码
user:
  username: zhangsan
  password: 123456
  mobilephone: 15336574540

这种情况,也可以把所有二级属性当成一级属性的对象,可以用类似 JSON 的格式把二级属性放在同一行,如下所示。

yaml 复制代码
user: {username: zhangsan,password: 123456,mobilephone: 15336574540}

YAML 配置多级属性示例:

yaml 复制代码
server:
  port: 82
  servlet:
    context-path: /good

YAML 配置属性值为数组示例:

yaml 复制代码
city:
  - beijing
  - shanghai
  - guangzhou
  - shenzhen

也可以用单行模式代替上述配置:

yaml 复制代码
city: [beijing,shanghai,guangzhou,shenzhen]

属性的值是对象数组的示例:

yaml 复制代码
books:
  - name: 三国演义
    author: 罗贯中
    price: 88
  - name: 西游记
    author: 吴承恩
    price: 100

也可以使用单行模式代替上述配置:

yaml 复制代码
books: [{name: 三国演义,author: 罗贯中,price: 88},{name: 西游记,author: 吴承恩,price: 100}]

读取配置文件

使用@Value 注解
java 复制代码
@Value("${mobilephone}")
String mobilephone;
@Test
void testUserName(){
    System.out.println(username);
}
  • 读取多级属性的值,代码如下所示:
java 复制代码
@Value("${user.username}")
String username;
  • 读取数组中的一个元素,代码如下所示。
java 复制代码
@Value("${city[2]}")
String city;
  • 读取对象数组中的一个对象的某个属性值,这里读取第二本书的名称
java 复制代码
@Value("${books[1].name}")
String bookName;
  • 变量引用

如果配置文件中的某一个属性的值还要在其他多个属性中使用 ,则其他属性的值中可以用 SPEL 表达式${被引用的属性名称}的办法进行引用,相当于使用了一个变量,其好处之一是其他属性无须重复编写相同值,好处之二是一旦被引用的 属性的值改变,引用了该属性的其他属性的值也跟着改变而无须一个个手动修改。

使用 Environment 对象

可以使用 Environment 一次性获取所有配置文件中的所有信息。Spring Boot 启动后,配置文件中的数据默认都封装到 Envirmonment 类的 Bean 中, 只有使用 @Autowired 注解流入该 Bean 即可获得任意一个配置项的值。获取值使用 Envirmonment 类的 getProperty 方法,要获取哪个配置项则方法的参数就使用该配置项的名称。

  • 使用 Envirmonment 获得 username 和 password 的值
java 复制代码
@Autowired
Environment environment;
@Test
void testEnvironment(){
    System.out.println("mobilephone:"+environment.getProperty("mobilephone"));
}
使用@ConfigurationProperties 注解

实现一次性加载某个前缀的数据,封装到一个实体类中,例如,配置文件中有个 user 属性,该属性下面还有若干个二级属性,user 属性可以当成是前缀,这样可以将 user 下的所有二级属性一次性自动封装到 User 实体类中来并同时创建成一个 Bean。具体步骤如下。

(1)首先创建一个实体类 User,类中的属性与配置文件中的 user 属性下的所有二级属性完全相同。

java 复制代码
@Data
@Accessors(chain = true)
@Component
@ConfigurationProperties(prefix = "user")
public class UserInfo {
    private String username;
    private String password;
    private String mobilephone;
}

然后在实体类中添加注解:

java 复制代码
@Component
@ConfigurationProperties(prefix = "user")

(2)在测试类中添加如下代码:

java 复制代码
@Autowired
UserInfo userInfo;
@Test
void testUser(){
    System.out.println(userInfo);
}

多环境配置

常用的三个环境配合文件

  • 开发环境:application-dev.yml
  • 测试环境:application-test.yml
  • 生产环境:application-prod.yml

1.各个配置文件模拟数据库的配置信息不同,内容分别如下

application-dev.yml:

yaml 复制代码
db:
  url: jdbc:mysql:///db1
  username: dev
  password: 123456

application-prod.yml:

yaml 复制代码
db:
  url: jdbc:mysql:///db2
  username: prod
  password: 123

application-test.yml:

yaml 复制代码
db:
  url: jdbc:mysql:///db3
  username: test
  password: 1234

2.选择环境。将 application.properties 配置文件修改为 application.yml,使用以下代码选择上述其中一个环境:

properties 复制代码
spring.profiles.active=dev

3.测试

java 复制代码
@RestController
public class HelloController {
    @Value("${db.url}")
    private String url;
    @Value("${db.username}")
    private String username;
    @Value("${db.password}")
    private String password;
    @GetMapping("/test")
    public String test(){
        String str="<h1>服务端数据库信息如下</h1>";
        str+="<h2>url:"+url+"</h2>";
        str+="<h2>username:"+username+"</h2>";
        str+="<h2>password:"+password+"</h2>";
        return str;
    }
}

热部署

一般情况下,在项目的开发过程中,如果代码修改了,需要重新启动项目修改才会生效。但可以进行热部署实现无需重新手动重启应用程序。

1.首先要在 IDEA 中进行自动构建项目的配置,选择菜单【File】->【Setting】->【Build,Execution,Deployment】-> 【Complier】,然后 在右侧部 分勾选 Build project automatically 选项

2.修改pom.xml

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>

3.在application.yml中添加

yaml 复制代码
spring:
  devtools:
    restart:
      enabled: true
相关推荐
魔道不误砍柴功1 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2341 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨1 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
种树人202408191 小时前
如何在 Spring Boot 中启用定时任务
spring boot
Chrikk3 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*3 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue3 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man3 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
测开小菜鸟3 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity4 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq