SpringBoot 框架1

简介: SpringBoot 框架

Spring Boot 是什么 (了解)

Spring Boot 是 Spring 开源组织下的子项目,其设计目的是专注于Spring应用的开发,开发人员可以把更多的精力放在业务代码上,而无需过多关注XML的配置,从而简化Spring应用开发,提高开发效率


Spring Boot 提供了大量开箱即用(out-of-the-box)的依赖模块,例如 spring-boot-starter-redis、spring-boot-starter-data-mongodb 和 spring-boot-starter-data-elasticsearch 等。这些依赖模块为 Spring Boot 应用提供了大量的自动配置,使得 Spring Boot 应用只需要非常少量的配置甚至零配置,便可以运行起来,让开发人员从 Spring 的“配置地狱”中解放出来,有更多的精力专注于业务逻辑的开发。


Spring Boot starter (了解)

Spring Boot 将日常企业应用研发中的各种场景都抽取出来,做成一个个的 starter(启动器),starter 中整合了该场景下各种可能用到的依赖,用户只需要在 Maven 中引入 starter 依赖,SpringBoot 就能自动扫描到要加载的信息并启动相应的默认配置。starter 提供了大量的自动配置,让用户摆脱了处理各种依赖和配置的困扰。所有这些 starter 都遵循着约定成俗的默认配置,并允许用户调整这些配置,即遵循“约定大于配置”的原则。


并不是所有的 starter 都是由 Spring Boot 官方提供的,也有部分 starter 是第三方技术厂商提供的,例如 druid-spring-boot-starter 和 mybatis-spring-boot-starter 等等。当然也存在个别第三方技术,Spring Boot 官方没提供 starter,第三方技术厂商也没有提供 starter。


<?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>
    <!--SpringBoot父项目依赖管理-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
        <relativePath/>
    </parent>
    ....
    <dependencies>
        <!--导入 spring-boot-starter-web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        ...
    </dependencies>
    ...
</project>

spring-boot-starter-parent 是所有 Spring Boot 项目的父级依赖,它被称为 Spring Boot 的版本仲裁中心,可以对项目内的部分常用依赖进行统一管理。


Spring Boot 项目可以通过继承 spring-boot-starter-parent 来获得一些合理的默认配置,它主要提供了以下特性:


默认 JDK 版本(Java 8)


默认字符集(UTF-8)


依赖管理功能


资源过滤


默认插件配置


识别 application.properties 和 application.yml 类型的配置文件


查看 spring-boot-starter- parent 的底层代码,可以发现其有一个父级依赖 spring-boot-dependencies。


<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.4.5</version>
</parent>

spring-boot-dependencies 的底层代码如下。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.4.5</version>
    <packaging>pom</packaging>
    ....
    <properties>
        <activemq.version>5.16.1</activemq.version>
        <antlr2.version>2.7.7</antlr2.version>
        <appengine-sdk.version>1.9.88</appengine-sdk.version>
        <artemis.version>2.15.0</artemis.version>
        <aspectj.version>1.9.6</aspectj.version>
        <assertj.version>3.18.1</assertj.version>
        <atomikos.version>4.0.6</atomikos.version>
        ....
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.activemq</groupId>
                <artifactId>activemq-amqp</artifactId>
                <version>${activemq.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.activemq</groupId>
                <artifactId>activemq-blueprint</artifactId>
                <version>${activemq.version}</version>
            </dependency>
            ...
        </dependencies>
    </dependencyManagement>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>build-helper-maven-plugin</artifactId>
                    <version>${build-helper-maven-plugin.version}</version>
                </plugin>
                <plugin>
                    <groupId>org.flywaydb</groupId>
                    <artifactId>flyway-maven-plugin</artifactId>
                    <version>${flyway.version}</version>
                </plugin>
                ...
            </plugins>
        </pluginManagement>
    </build>
</project>


以上配置中,部分元素说明如下:


dependencyManagement :负责管理依赖;


pluginManagement:负责管理插件;


properties:负责定义依赖或插件的版本号。


spring-boot-dependencies 通过 dependencyManagement 、pluginManagement 和 properties 等元素对一些常用技术框架的依赖或插件进行了统一版本管理,例如 Activemq、Spring、Tomcat 等。


YAML (熟悉)

什么是yaml?

YAML 是一种易读的数据序列化语言。它通常用于配置文件。与properties文件相比,YAML 文件具有结构化、有序、不容易混淆、分层、简洁的优点。


SpringBoot 默认使用以下 2 种全局的配置文件,其文件名是固定的。


application.properties


application.yml


YAML 语法

YAML 的语法如下:

  • 使用缩进表示层级关系。
  • 缩进时不允许使用 Tab 键,只允许使用空格。
  • 缩进的空格数不重要,但同级元素必须左侧对齐。
  • 大小写敏感。
spring:
  profiles: dev
  datasource:
    url: jdbc:mysql://127.0.01/banchengbang_springboot
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver


YAML 常用写法

YAML 支持以下三种数据结构:

  • 对象:键值对的集合
  • 数组:一组按次序排列的值
  • 字面量:单个的、不可拆分的值


YAML 字面量写法

字面量是指单个的,不可拆分的值,例如:数字、字符串、布尔值、以及日期等。


在 YAML 中,使用“key:[空格]value”的形式表示一对键值对(空格不能省略)


如 url: www.biancheng.net。


字面量直接写在键值对的“value”中即可,且默认情况下字符串是不需要使用单引号或双引号的。

name: bianchengbang

YAML 对象写法

在 YAML 中,对象可能包含多个属性,每一个属性都是一对键值对。

YAML 为对象提供了 2 种写法:

普通写法,使用缩进表示对象与属性的层级关系。

website: 
  name: bianchengbang
  url: www.biancheng.net

行内写法:

website: {name: bianchengbang,url: www.biancheng.net}



YAML 数组写法

YAML 使用“-”表示数组中的元素,普通写法如下:

pets:
  -dog
  -cat
  -pig


行内写法

pets: [dog,cat,pig]


复合结构

以上三种数据结构可以任意组合使用,以实现不同的用户需求,例如:

person:
  name: zhangsan
  age: 30
  pets:
    -dog
    -cat
    -pig
  car:
    name: QQ
  child:
    name: zhangxiaosan
    age: 2

YAML 组织结构

一个 YAML 文件可以由一个或多个文档组成,文档之间使用“---作为分隔符,且个文档相互独立,互不干扰。如果 YAML 文件只包含一个文档,则“---分隔符可以省略。

---
website:
  name: bianchengbang
  url: www.biancheng.net
---
website: {name: bianchengbang,url: www.biancheng.net}
pets:
  -dog
  -cat
  -pig
---
pets: [dog,cat,pig]
name: "zhangsan \n lisi"
---
name: 'zhangsan \n lisi'

*Spring Boot 配置绑定 (熟悉)

https://blog.csdn.net/qq_41946216/article/details/124771388


Spring Boot 导入Spring 配置(了解)

默认情况下,Spring Boot 中是不包含任何的 Spring 配置文件的,即使我们手动添加 Spring 配置文件到项目中,也不会被识别。


Spring Boot提倡基于Java的配置。尽管你可以使用XML源,不过还是建议你使用@Configuration类作为主要配置源。通常定义了main方法的类也是使用@Configuration注解的一个很好的替补。


使用@ImportResource注解加载Spring配置文件

在主启动类上使用 @ImportResource 注解可以导入一个或多个 Spring 配置文件,并使其中的内容生效。

在resources下创建beans.xml文件,如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="orderService" class="com.moming.service.impl.OrderServiceImpl"></bean>
</beans>
@SpringBootApplication
@ImportResource(value = "classpath:beans.xml")
public class App{
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

Spring Boot 推荐我们使用全注解的方式加载 Spring 配置,其实现方式如下:


使用 @Configuration 注解定义配置类,替换 Spring 的配置文件;


配置类内部可以包含有一个或多个被 @Bean 注解的方法,这些方法会被 AnnotationConfigApplicationContext 或 AnnotationConfigWebApplicationContext 类扫描,构建 bean 定义(相当于 Spring 配置文件中的<bean></bean>标签),方法的返回值会以组件的形式添加到容器中,组件的 id/name 就是方法名。


Spring Boot Profile (熟悉)

实际开发中会同时存在dev、uat、prod等多套环境,这些环境共用一套代码逻辑,但却需要不同的配置。例如dev环境要连接测试数据库,而prod则需要连接生产数据库等等。profile最主要的目的就是可以区分不同的环境,进而对不同环境进行配置。使用方法就是在配置文件中通过spring.profiles.active来指定需要使用的配置文件,也就是激活


当profile为default时,只使用application.yaml,SpringBoot默认Server端口为8080。将当前profile激活为dev时, SpringBoot就会额外加载application-dev.yaml 后合并到application.yaml中,若其中有相同的配置则覆盖掉。


Spring Boot配置 profile

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


profile配置方法

  • 多profile文件方式
  • yml多文档方式


profile激活方法

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


演示

一、创建不同的application.properties配置文件(多profile文件方式)

下面创建application-dev(开发配置文件,端口8081)、application-test(测试配置文件,端口8082)、application-pro(生产配置文件,端口8083),并设置不同的配置文件下的端口。


application-dev.properties
server.port = 8081


application-test.properties
server.port = 8082


application-pro.properties
server.port = 8083


如果需要调用对应的端口,则需要在application配置文件中对相应的端口进行激活开放

application
spring.profiles.active = dev #开放application-dev.properties的端口
spring.profiles.active = test#开放application-test.properties的端口
spring.profiles.active = pro#开放application-pro.properties的端口
#其中spring.profiles.active的值为不同配置文件的后缀名


二、创建一个application.yml文件(yml多文档方式)

在application.yml配置文件中,通过 - - - 对不同profile配置进行区分,并通过Spring Boot中的profiles对不同profile进行命名


---
server:
  port: 8081
spring:
  profiles: dev
---
server:
  port: 8082
spring:
  profiles: test
---
server:
  port: 8083
spring:
  profiles: pro
---
#不同profile的激活,通过修改active的值,从而达到对不同的profile的激活
spring:
  profiles:
    active: dev


Spring Boot 默认配置文件(熟悉)

通常情况下,Spring Boot 在启动时会将 resources 目录下的 application.properties 或 apllication.yml 作为其默认配置文件,我们可以在该配置文件中对项目进行配置,但这并不意味着 Spring Boot 项目中只能存在一个 application.properties 或 application.yml。


默认配置文件顺序

Spring Boot 项目中可以存在多个 application.properties 或 apllication.yml。


SpringBoot项目启动会扫描以下位置的application.properties或者application.yml文件作为SpringBoot的默认配置文件,具体的目录如下所示。


1.file:./config/ ( 项目根路径下的config文件夹)


2.file:./ (项目根路径)


3.classpath:/config/ (类路径下的config文件夹)


4.classpath:/ (类路径)


注:file: 指当前项目根目录;classpath: 指当前项目的类路径,即 resources 目录。

以上所有位置的配置文件都会被加载,且它们优先级依次降低,序号越小优先级越高。其次,位于相同位置的 application.properties 的优先级高于 application.yml。


所有位置的文件都会被加载,高优先级配置会覆盖低优先级配置,形成互补配置,即:


存在相同的配置内容时,高优先级的内容会覆盖低优先级的内容;


存在不同的配置内容时,高优先级和低优先级的配置内容取并集。

优先级:8081>8082>8083>8084


优先级由高到底,高优先级的配置会覆盖低优先级的配置,没有的配置进行互补配置。


注意:不是类路径下的配置文件在打包时,如果不做配置是不会打包进jar中的,也会是说前两个配置在项目打包后,包中是不存在的,所以尽量不要用前两个位置。


Spring Boot 外部配置文件(熟悉)

除了默认配置文件,Spring Boot 还可以加载一些位于项目外部的配置文件。我们可以通过如下 2 个参数,指定外部配置文件的路径:

  • spring.config.location
  • spring.config.additional-location


spring.config.location

我们可以先将 Spring Boot 项目打包成 JAR 文件,然后在命令行启动命令中,使用命令行参数 --spring.config.location,指定外部配置文件的路径。


java -jar {JAR}  --spring.config.location={外部配置文件全路径}
java -jar springbootdemo-0.0.1-SNAPSHOT.jar  --spring.config.location=D:\myConfig\my-application.yml

需要注意的是,使用该参数指定配置文件后,会使项目默认配置文件(application.properties 或 application.yml )失效,Spring Boot 将只加载指定的外部配置文件。我们可以通过以下 3 种方式解决这个问题。


在 IDEA 的运行配置(Run/Debug Configuration)中,添加虚拟机参数 -Dspring.config.additional-location=D:\myConfig\my-application.yml,指定外部配置文件;


在 IDEA 的运行配置(Run/Debug Configuration)中,添加程序运行参数 --spring.config.additional-location=D:\myConfig\my-application.yml,指定外部配置文件;


在主启动类中调用 System.setProperty()方法添加系统属性 spring.config.additional-location,指定外部配置文件。


spring.config.additional-location

我们还可以在 Spring Boot 启动时,使用命令行参数 --spring.config.additional-location 来加载外部配置文件。

java -jar {JAR}  --spring.config.additional-location={外部配置文件全路径}
java -jar springbootdemo-0.0.1-SNAPSHOT.jar  --spring.config.additional-location=D:\myConfig\my-application.yml

但与 --spring.config.location 不同,--spring.config.additional-location 不会使项目默认的配置文件失效,使用该命令行参数添加的外部配置文件会与项目默认的配置文件共同生效,形成互补配置,且其优先级是最高的,比所有默认配置文件的优先级都高。


注意:Maven 对项目进行打包时,位于项目根目录下的配置文件是无法被打包进项目的 JAR 包的,因此位于根目录下的默认配置文件无法在 JAR 中生效,即该项目将只加载指定的外部配置文件和项目类路径(classpath)下的默认配置文件,它们的加载优先级顺序为:


1.spring.config.additional-location 指定的外部配置文件 my-application.yml


2.classpath:/config/application.yml


3.classpath:/application.yml


实战演示:http://c.biancheng.net/spring_boot/external-config.html


Spring Boot 配置加载顺序(熟悉)

SpringBoot 常用的几种配置形式,按照配置生效的优先级从高到低排列

命令行参数> 操作系统环境变量>配置文件(YAML 文件、Properties 文件)>@Configuration 注解类上的@PropertySource 指定的配置文件


默认配置文件顺序

Spring Boot 项目中可以存在多个 application.properties 或 apllication.yml。


SpringBoot项目启动会扫描以下位置的application.properties或者application.yml文件作为SpringBoot的默认配置文件,具体的目录如下所示。


file:./config/ ( 项目根路径下的config文件夹)


file:./ (项目根路径)


classpath:/config/ (类路径下的config文件夹)


classpath:/ (类路径)


注:file: 指当前项目根目录;classpath: 指当前项目的类路径,即 resources 目录。

以上所有位置的配置文件都会被加载,且它们优先级依次降低,序号越小优先级越高。其次,位于相同位置的 application.properties 的优先级高于 application.yml。


所有位置的文件都会被加载,高优先级配置会覆盖低优先级配置,形成互补配置,即:


存在相同的配置内容时,高优先级的内容会覆盖低优先级的内容;


存在不同的配置内容时,高优先级和低优先级的配置内容取并集。



优先级:8081>8082>8083>8084


优先级由高到底,高优先级的配置会覆盖低优先级的配置,没有的配置进行互补配置。


注意:不是类路径下的配置文件在打包时,如果不做配置是不会打包进jar中的,也会是说前两个配置在项目打包后,包中是不存在的,所以尽量不要用前两个位置。


Spring Boot 自动配置原理(熟悉)

我们知道SpringBoot可以帮我们减少很多的配置,也肯定听过“约定大于配置”这么一句话,那SpringBoot是怎么做的呢?其实靠的就是@EnableAutoConfiguration注解。

简单来说,这个注解可以帮助我们自动载入应用程序所需要的所有默认配置。


发现有两个比较重要的注解

  • @AutoConfigurationPackage:自动配置包
  • @Import(AutoConfigurationImportSelector.class):给IOC容器导入组件


@AutoConfigurationPackage


我们可以发现,依靠的还是@Import注解


@AutoConfigurationPackage注解就是在默认的情况下就是将主配置类@SpringBootApplication这个注解所在包及其子包里边的组件扫描到Spring容器中


看起来跟@ComponentScan注解一样的作用,但是扫描的对象不一样,比如说,你用了Spring Data JPA,可能会在实体类上写@Entity注解。这个@Entity注解由 @AutoConfigurationPackage扫描并加载,而我们平时开发用的@Controller/@Service/@Component/@Repository这些注解是由@ComponentScan来扫描并加载的。


简单理解:这二者扫描的对象是不一样的。


@Import(AutoConfigurationImportSelector.class)

AutoConfigurationImportSelector这个类中有个selectImports方法,其中getCandidateConfigurations方法可以获取很多的配置信息

那这些配置信息哪里来的呢?

这里包装了一层,我们看到的只是通过SpringFactoriesLoader来加载获取到的配置信息,还没看到关键信息,继续进去:


解析

FACTORIES_RESOURCE_LOCATION(工厂资源加载路径)的值是META-INF/spring.factories


Spring启动的时候会扫描所有jar路径下的META-INF/spring.factories,将其文件包装成Properties对象


从Properties对象获取到key值为EnableAutoConfiguration的数据,然后添加到容器里边。

最后我们会默认加载113个默认的配置类:


目录
相关文章
|
3天前
|
Java 数据安全/隐私保护 Spring
Java 中 Spring Boot 框架下的 Email 开发
Java 中 Spring Boot 框架下的 Email 开发
28 2
|
3天前
|
缓存 前端开发 Java
【框架】Spring 框架重点解析
【框架】Spring 框架重点解析
18 0
|
3天前
|
XML Java 数据格式
Spring框架入门:IoC与DI
【5月更文挑战第15天】本文介绍了Spring框架的核心特性——IoC(控制反转)和DI(依赖注入)。IoC通过将对象的创建和依赖关系管理交给容器,实现解耦。DI作为IoC的实现方式,允许外部注入依赖对象。文章讨论了过度依赖容器、配置复杂度等常见问题,并提出通过合理划分配置、使用注解简化管理等解决策略。同时,提醒开发者注意过度依赖注入和循环依赖,建议适度使用构造器注入和避免循环引用。通过代码示例展示了注解实现DI和配置类的使用。掌握IoC和DI能提升应用的灵活性和可维护性,实践中的反思和优化至关重要。
17 4
|
3天前
|
安全 Java Spring
Spring框架中的单例Bean是线程安全的吗?
Spring框架中的单例Bean是线程安全的吗?
10 1
|
3天前
|
安全 Java 开发者
如何在Spring框架中实现横切关注点的集中管理和重用?
【4月更文挑战第30天】如何在Spring框架中实现横切关注点的集中管理和重用?
19 0
|
3天前
|
前端开发 Java 开发者
【JavaEE】面向切面编程AOP是什么-Spring AOP框架的基本使用
【JavaEE】面向切面编程AOP是什么-Spring AOP框架的基本使用
9 0
|
3天前
|
JSON 前端开发 Java
【JavaEE】让“单车变摩托”的神级框架—Spring MVC的深入讲解(下)
【JavaEE】让“单车变摩托”的神级框架—Spring MVC的深入讲解
6 0
|
3天前
|
JSON 前端开发 Java
【JavaEE】让“单车变摩托”的神级框架—Spring MVC的深入讲解(上)
【JavaEE】让“单车变摩托”的神级框架—Spring MVC的深入讲解
5 0
|
3天前
|
XML Java 应用服务中间件
【JavaEE】JavaEE进阶:框架的学习 - Spring的初步认识
【JavaEE】JavaEE进阶:框架的学习 - Spring的初步认识
6 0
|
3天前
|
XML Java 数据库连接
Spring框架与Spring Boot的区别和联系
Spring框架与Spring Boot的区别和联系
24 0