Spring Boot | Spring Boot的“核心配置“与“注解“

news2024/11/19 13:33:55

目录:

  • Spring Boot的核心配置与注解 :
    • 1. 全局配置文件 ( application.properties / application.yaml:创建项目时候自动生成,其会被“自动导入”到“程序”中 )
      • application.properties配置文件
      • application.yaml 配置文件 (推荐使用)
        • 当value值为 “普通数据类型” (如 : 数字、字符串、布尔等)
        • 当value值为 “数组” 或 “单列集合”
        • 当value值为 “Map集合” 或 “对象类型”
        • application.yaml 配置文件的“应用案例”
    • 2. “配置文件属性值” 的 “注入”
      • 使用@ConfigurationProperties( )注解将“配置文件”中的“属性值”注入到“属性”中 (注入“个别属性值”)
      • 使用@Value( )注解将“配置文件”中的“属性值”注入到“属性”中 (注入“个别属性值”)
      • 两种注解“对比分析”
        • 底层框架
        • 功能
        • 属性 setter 方法
        • 复杂类型属性注入
        • 松散绑定
        • JSR303 数据校验
        • SpEL表达式 ( 使用“SpEL表达式”为属性“直接注入值” )
      • 如何选择使用这“两种注解”?

Spring Boot的核心配置与注解 :

在这里插入图片描述

作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!

该文章参考学习教材为:
《Spring Boot企业级开发教程》 黑马程序员 / 编著
文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章

文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!

(侵权可联系我,进行删除,如果雷同,纯属巧合)


1. 全局配置文件 ( application.properties / application.yaml:创建项目时候自动生成,其会被“自动导入”到“程序”中 )

  • 全局配置文件 ( applicationContext.properties )能够对一些 默认配置值进行修改Spring Boot 使用一个 ① application.properties 或者 ② application.yaml文件作为 全局配置文件该文件存放src/main/resource目录 或者 类路径的 /config,一般会选择 resource目录

application.properties配置文件

  • 使用 Spring Initializr方式构建Spring Boot项目时,会在 src/main/resources目录自动生成一个空 application.properties文件Spring Boot项目启动时自动加载application.properties文件

  • 我们可以在application.properties 文件中定义 Spring Boot 项目相关属性,当然,这些相关属性可以是 系统属性环境变量命令参数等信息,也可以是 自定义配置文件名称位置示例代码如下:

    spring.application.name=chapter_02
    server.address=80
    server.port=8443
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.config.additional-location=
    spring.config.location=
    spring.config.name=application
    
  • 关于applicationContext.properties案例 ( 例子如 ) :

    Pet.java :

    package com.myh.chapter_03.domain;
    
    public class Pet {
    
        private String type;
        private String name;
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Pet{" +
                    "type='" + type + '\'' +
                    ", name='" + name + '\'' +
                    '}';
        }
    
    }
    

    Person.java

    package com.myh.chapter_03.domain;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    
    @Component //用于将Person类加入到IOC容器中 (只有这样Person对象才能被 @ConfigurationProperties()注解赋值 )
    
    @ConfigurationProperties(prefix = "person")//将配置文件(application.properties)中以person开头的数据通过“set方法”注入到该类中"属性"
    public class Person {
    
        /**
         * 通过 @ConfigurationProperties(prefix = "person") 注解来将 application.properties中的"数据"注入到
         * 下面的“属性”中
         */
        private int id;
        private String name;
        private List hobby;
        private String[] family;
        private Map map;
        private Pet pet;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List getHobby() {
            return hobby;
        }
    
        public void setHobby(List hobby) {
            this.hobby = hobby;
        }
    
        public String[] getFamily() {
            return family;
        }
    
        public void setFamily(String[] family) {
            this.family = family;
        }
    
        public Map getMap() {
            return map;
        }
    
        public void setMap(Map map) {
            this.map = map;
        }
    
        public Pet getPet() {
            return pet;
        }
    
        public void setPet(Pet pet) {
            this.pet = pet;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", hobby=" + hobby +
                    ", family=" + Arrays.toString(family) +
                    ", map=" + map +
                    ", pet=" + pet +
                    '}';
        }
    }
    

    @ConfigurationProperties(prefix =“person”)注解作用 是将配置文件person开头属性值通过setter方法注入实体类对应属性 中。@Component注解 的作用是当前注入属性值的 Person类对象作为 Bean 组件放到 Spring 容器中,只有 这样它才能被 @ConfigurationProperties注解赋值

    上述自定义 Person类中,添加了一个 @Component注解,将该自定义类作为 Spring容器的组件 ( 简而言之,就是 该类给IOC容器管理 ),其根本目的是让 Spring Boot 可以自动扫描到该组件,然后进行其他功能实现。


    application.properties

    #对实体类对象Person进行属性配置
    person.id = 1
    person.name = tom
    person.hobby = play,read,sleep
    person.family = father,mother
    person.map.k1 = v1
    person.map.k2 = v2
    person.pet.type = dog
    person.pet.name = kity
    

    Spring Boot默认全局配置文件 : application.properties 中的数值将会通过 @ConfigurationProperties( ) 注解 注入到对应实体类 中。


    pom.xml

    <?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.1.3.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <groupId>com.myh</groupId>
        <artifactId>chapter_03</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>chapter_03</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <!--    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>
    
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter</artifactId>
                <version>RELEASE</version>
                <scope>test</scope>
            </dependency>
    
            <!--   “热部署”依赖启动器   -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
    
            <!--   是生成配置元数据,以提供更好的配置文件支持和开发体验。它能够帮助开发人员更方便地使用配置文件,并提高开发效率   -->
            <!--
              在编写application.properties配置文件时,由于要配置的Person 对象属性是我们自定义的,SpringBoot 无法自动识别,所以不会有任何书写提示。在实际开发中,为了出现代码提示的效果来方便配置,在使用@ConfigurationProperties注解进行配置文件属性值注入时,可以在pom.xmI文件中添加一个Spring Boot 提供的配置处理器依赖
                 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
            </dependency>
        </dependencies>
    
        <!--    Maven打包工具插件   -->
    <!--    <build>-->
    <!--        <plugins>-->
    <!--            <plugin>-->
    <!--                <groupId>org.springframework.boot</groupId>-->
    <!--                <artifactId>spring-boot-maven-plugin</artifactId>-->
    <!--            </plugin>-->
    <!--        </plugins>-->
    <!--    </build>-->
    
    </project>
    

    Chapter03ApplicationTests.java ( 单元测试类 ):

    package com.myh.chapter_03;
    
    import com.myh.chapter_03.domain.Person;
    import org.junit.jupiter.api.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class) //测试运行器,并加载SpringBoot测试注解
    @SpringBootTest //标记该类为“单元测试类”,并加载项目的上下文环境ApplicationContext
    class Chapter03ApplicationTests {
    
        @Autowired
        private Person person;
    
        @Test
        void contextLoads() {
            System.out.println(person);
        }
    }
    

    运行 contextLoads( )方法控制台输出结果如下图所示 :
    在这里插入图片描述
    方法执行结果.jpg)信息成功打印,说明了 application.properties文件 属性配置正确,并通过 相关注解自动完成属性注入

application.yaml 配置文件 (推荐使用)

  • YAML文件格式Spring Boot 支持 的一种 JSON 超集文件格式,相较于传统Properties配置文件YAML文件数据核心,是一种更为 直观容易被计算机识别数据序列化格式
  • application.yaml 配置文件的 工作原理application.properties一样的,只不过YAML格式配置文件看起来 更简洁一些
  • application.yaml 文件用“ key: + 空格 + value”格式配置属性,使用缩进控制层级关系。这里我们 针对不同数据类型属性值,介绍一下YAML文件配置属性写法,具体如下所示 。
当value值为 “普通数据类型” (如 : 数字、字符串、布尔等)
  • (1) value 值为 普通数据类型( 如数字字符串布尔等)
    YAML 配置文件中配置的 属性值普通数据类型 时,可以 直接配置对应属性值,同时对 字符串类型属性值不需要额外添加引号示例代码如下

    #当属性值为普通数据类型(如:数字、字符串、布尔等),属性值不需要”额外添加引号“
    #8081 和 /hello因为是"普通数据类型",所以都没添加额外的引号
    #port和path属于“同一级别”
    Server:
      port: 8081
      path: /hello
    
当value值为 “数组” 或 “单列集合”
  • (2) value 值为 数组单列集合
    YAML 配置文件中配置的 属性值数组单列集合类型 时,主要有 两种书写方式①缩进式写法②行内式写法

    ①缩进式写法 :

    #缩进式写法
    person1:
      hobby:
        - play
        - read
        - sleep
    
    person2:
      hobby:
        play,
        read,
        sleep  
    

    ②行内式写法 :

    #行内式写法
    person4:
      hobby: [play,read,sleep]
    
    #使用行内式设置属性值时, []是可以省略的,程序会自动匹配校队"属性的值"
    person5:
      hobby: play,read,sleep
    
当value值为 “Map集合” 或 “对象类型”
  • (3) value 值为 Map 集合对象类型 时,主要同样 有两种书写方式①缩进式写法②行内式写法

    ①缩进式写法 :

    #value值为Map或对象时的写法
    #Map类型
    #缩进式写法
    person6:
      map:
        k1: v1
        k2: v2
    

    ②行内式写法 :

    #Map类型
    #行内式写法,此处用的符号是: 大括号{}
    person7:
      map: {k1: v1,k2: k3}
    

    ps :

    此处用的 符号 是: 大括号{ }

application.yaml 配置文件的“应用案例”
  • application.yaml :

    #对实体类对象Person进行属性设置, 一样是通过 @ConfigurationProperties()注解来将下面的"数据值"注入到"类"的"属性"中的
    person2:
      id: 1
      name: 张三
      hobby: [play,read,sleep]
      family: [father,mother]
      map: {k1: v1,k2: v2}
      pet: {type: dog,name: kitty}
    

    Person.java :

    package com.myh.chapter_03.domain;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    
    @Component //用于将Person类加入到IOC容器中 (只有这样Person对象才能被 @ConfigurationProperties()注解赋值 )
    
    @ConfigurationProperties(prefix = "person2")//将配置文件( application.yaml )中以person2开头的数据通过“set方法”注入到该类中"属性"
    public class Person {
    
        /**
         * 通过 @ConfigurationProperties(prefix = "person") 注解来将 application.properties中的"数据"注入到
         * 下面的“属性”中
         */
        private int id;
        private String name;
        private List hobby;
        private String[] family;
        private Map map;
        private Pet pet;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List getHobby() {
            return hobby;
        }
    
        public void setHobby(List hobby) {
            this.hobby = hobby;
        }
    
        public String[] getFamily() {
            return family;
        }
    
        public void setFamily(String[] family) {
            this.family = family;
        }
    
        public Map getMap() {
            return map;
        }
    
        public void setMap(Map map) {
            this.map = map;
        }
    
        public Pet getPet() {
            return pet;
        }
    
        public void setPet(Pet pet) {
            this.pet = pet;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", hobby=" + hobby +
                    ", family=" + Arrays.toString(family) +
                    ", map=" + map +
                    ", pet=" + pet +
                    '}';
        }
    }
    

    Chapter03ApplicationTests.java ( 单元测试类 ):

    package com.myh.chapter_03;
    
    import com.myh.chapter_03.domain.Person;
    import org.junit.jupiter.api.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class) //测试运行器,并加载SpringBoot测试注解
    @SpringBootTest //标记该类为“单元测试类”,并加载项目的上下文环境ApplicationContext
    class Chapter03ApplicationTests {
    
        @Autowired
        private Person person;
    
        @Test
        void contextLoads() {
            System.out.println(person);
        }
    }
    

    运行 contextLoads( )方法控制台输出结果如下图所示 :
    在这里插入图片描述
    信息成功打印,说明了 application.yaml文件 属性配置正确,并通过 相关注解自动完成属性注入

    通过对比可以发现YAML配置文件的格式更加简洁、方便推荐使用YAML格式文件

2. “配置文件属性值” 的 “注入”

  • 使用Spring Boo 全局配置文件 ( application.properties / application.yaml )配置 属性 时, 如果配置的属性Spring Boot 默认提供的属性 ,例如服务器端口server.port,那么Spring Boot内部会自动扫描并读取属性值 ( 因为那是 默认提供的属性 )。 如果配置的属性是 用户自定义属性,例如 :自定义Person 实体类属性,则必须在程序中注入这些配置属性 ( 通过 @ConfigurationProperties( )注解进行“属性值”的注入 )方可生效。

  • Spring Boot 支持 多种注入配置文件属性方式 :

    使用 注解@ConfigurationProperties ( )注解“注入属性” 使用 @Value( )注解 “注入属性”

使用@ConfigurationProperties( )注解将“配置文件”中的“属性值”注入到“属性”中 (注入“个别属性值”)

  • Spring Boot提供的 @ConfigurationProperties注解 用来快速、方便地 配置文件中自定义
    属性值批量注入 某个Bean 对象多个对应属性
    中。假设现在有一个配置文件,使用 @ConfigurationProperties 注入配置文件的属性示例代码如下 :

    @Component //将该类交给IOC容器管理,变成一个bean
    //该注解的作用: 将配置文件中自定义的"属性值"注入到某个bean对象中的"对应属性"中
    @ConfigurationProperties(prefix = "person")//将配置文件( application.properties/application.yaml )中以后person开头的数据通过“set方法”注入到该类中"属性"
    public class Person {
        private int id;
        
        //属性的set方法
        public void setId(int id) {
            this.id = id;
        }
    }
    

    上述代码使用 @Component@ConfigurationProperties(prefix =“person”)配置文件中每个属性映射person类属性中
    需要注意 的是,使用 @ConfigurationProperties 注解 批量注入属性值 时,要保证配置文件中的 属性 与对应实体类的 属性名一致否则无法 正确 获取并注入属性值

使用@Value( )注解将“配置文件”中的“属性值”注入到“属性”中 (注入“个别属性值”)

  • @Value注解Spring框架提 供的,用来 读取配置文件中的属性值 并逐个 注入Bean对象对应属性Spring Boot 框架对Spring 框架中的 @Value注解进行了 默认继承,所以在Spring Boot 框架中还可以使用该注解 读取注入配置文件属性值

    @Component //将该类交给IOC容器管理,变成一个bean
    public class Person {
        
        @Value("${person.id}") //将配置文件中的“属性值”注入到该类的属性中
        private int id;
    }
    

    上述代码中,@Component注解@Value注解用于 注入Personid属性。其中,@Value 不仅支持注入Person的 id 属性,而且 还可以直接id属性赋值,这是 @ConfigurationProperties( )注解 不支持 的。

  • 例子如

    Student.java

    package com.myh.chapter_03.domain;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    
    @Component //将该类添加到IOC容器中,作为一个bean(被IOC容器管理)
    public class Student {
    
        //用该注解将配置文件中的"属性值"注入到该类的“属性”中
        @Value("${person.id}")
        private int id;
        @Value("${person.name}")
        private String name;
        private List hobby;
        private String[] family;
        private Map map;
        private Pet pet;
    
        @Override
        public String toString() {
            return "Student{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", hobby=" + hobby +
                    ", family=" + Arrays.toString(family) +
                    ", map=" + map +
                    ", pet=" + pet +
                    '}';
        }
    }
    

    pom.xml

    #对实体类对象Person进行属性设置, 一样是通过 @ConfigurationProperties()注解来将下面的"数据值"注入到"类"的"属性"中的
    person:
      id: 1
      name: tom
      hobby: [play,read,sleep]
      family: [father,mother]
      map: {k1: v1,k2: v2}
      pet: {type: dog,name: kitty}
    

    Chapter03ApplicationTests.java (测试类):

    package com.myh.chapter_03;
    
    import com.myh.chapter_03.domain.Person;
    import com.myh.chapter_03.domain.Student;
    import org.junit.jupiter.api.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class) //测试运行器,并加载SpringBoot测试注解
    @SpringBootTest //标记该类为“单元测试类”,并加载项目的上下文环境ApplicationContext
    class Chapter03ApplicationTests {
    
        @Autowired
        private Student student;
        
        @Test
        public void studentTest() {
            System.out.println(student);
        }
    }
    

    运行 studentTest( )方法控制台输出结果如下图所示 :
    在这里插入图片描述

    注意点

    使用 @Value( )注解 注入的 属性类型 只能是“ 基本数据类型”。

两种注解“对比分析”

  • @ConfigurationProperties( )注解@Value( )注解对比 如下表所示

    对比@ConfigurationProperties( )注解@Value( )注解
    底层框架SpringBootSpring
    功能批量注入配置文件中的属性单个注入
    setter 方法需要不需要
    复杂类型属性注入支持支持
    松散绑定支持不支持
    JSR303 数据校验支持不支持
    SpEL表达式不支持支持
底层框架

@ConfigurationProperties注解是 Spring Boot框架自带 的;而 @Value 注解Spring 框架支持的,
只不过Spring Boot框架对Spring 进行了 默认支持,所以也可以使用@Value 注解的相关功能。

功能

@ConfigurationProperties能够将配置文件中的属性 批量注入 Bean对象,而@Value 只能 一个一个单独注入

属性 setter 方法
  • 在使用 @ConfigurationProperties注解进行配置文件 属性值读取注入 时,还必须为 每一个属性 设置 setter方法,通过对应的注解才能够将配置文件中属性一一匹配并注入对应的 Bean 属性上。如果配置文件中没有配置属性值,则会自动将对应的 Bean 属性设置为空。
    @ConfigurationProperties注解必须为每一个属性设setter方法,这样才能完成属性值的注入
  • @Value 完全不需要为属性设置setter方法,该注解会先通过表达式读取配置文件中指定的属性值,然后自动注入下方的Bean属性上。如果读取的配置文件属性为空,进行属性注入时程序会自动报错
复杂类型属性注入

@ConfigurationProperties( )注解 和 @Value注解 支持 任意数据类型属性注入,包括基本数据类型复杂数据类型

松散绑定
  • @ConfigurationProperties注解进行配置文件属性注入时,支持松散绑定语法。例如Person类有一个字符串类型的属性firstName,那么在配置文件中进行属性配置时可以使用如下配置方式示例代码如下 :

    person.firstName = james //标准写法,对应Person类属性名
    person.first-name = james //使用横线“-”分隔多个单词
    person.first_name = james //使用下划线"_"分隔多个单词
    person.FIRST_NAME = james //使用大小写格式,推荐常量属性配置
    
    

    如果要 注入上述松散绑定语法属性,那么使用 @Value 注入无效的,只能使用@ConfigurationProperties

JSR303 数据校验
  • @ConfigurationProperties注解进行配置文件属性值注入时,支持JSR303数据校验 ,其主要作用是 校验配置文件注入对应Bean属性 的值是否符合相关值的规则,示例代码如下 :

    @Component //加入到IOC容器中
    @ConfigurationProperties(prefix = "person")
    @Validated //引入Spring框架支持的"数据校验规则"
    public class Example {
    
        @Email //对属性进行规则匹配
        private String email;
    
        public void setEmail(String email) {
            this.email = email;
        }
    }
    
    

    上述代码中,使用 @ConfigurationProperties注解注入配置文件属性值时,在实体类Example上引入 @Validated 注解行数据校验,在属性email 上引入@Email 注解进行邮件规则校验。如果注入的配置文件属性值不符合相关校验规则,程序会自动报错。@Value 注解不支持 JSR303数据校验功能

SpEL表达式 ( 使用“SpEL表达式”为属性“直接注入值” )
  • @Value 注解 注入配置文件属性时,支持 SpEL表达式语法,即“#{xx}”。例如 Person 类有一个整数类型的属性id,直接使用 SpEL 表达式语法进行属性注入使用SpEL表达式直接为属性注入值
    示例代码如下

     //用SpEL来定义一个值, #{5*2} 是一个简单的数学表达式,它计算 5乘以 2的结果,将给结果注入到id属性中 
    @Value("#{5*2}") 
    private int id;
    

    上述代码不使用配置文件 的情况下,直接使用 @Value注解 支持的 SpEL表达式注入Bean ( 通过该 注解支持的SpEL表达式来“直接”为“属性注入值 )。而 @ConfigurationProperties注解 不支持此功能

如何选择使用这“两种注解”?

  • 如果只是针对某一个业务需求,要引入配置文件中个别属性值,推荐使用 @Value( )注解
    ( 如果只要 注入一两个属性值,用 @Value( )注解
  • 如果针对某个JavaBean类,需要 批量注入属性值,则推荐使用@ConfigurationProperties( )注解
    注解。
    (如果要 注入多个属性值推荐使用 @ConfigurationProperties( )注解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1547768.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

模板设计模式经典案例

模板设计模式讲究的是将不变的设置为基类&#xff0c;将变的设置为虚函数来让子类实现。下面就以这样的写下模板设计模式的例子。 例子场景 一个工程步骤分为step1,step2&#xff0c;其中step1由总工程指定&#xff0c;step2由子工程指定&#xff0c;最后由一个函数串起来&am…

Android TargetSdkVersion 30 安装失败 resources.arsc 需要对齐且不压缩。

公司项目&#xff0c;之前targetSDKVersion一直是29&#xff0c;近期小米平台上架强制要求升到30&#xff0c;但是这个版本在android12上安装失败&#xff0c;我用adb命令安装&#xff0c;报错如下图 adb: failed to install c: Program Files (x86)(0A_knight\MorkSpace \Home…

SpringDoc 注解

列举几个常用的 1. Tag 用于说明或定义的标签。一般作用于控制层 2.Operation(summary "这是新增方法") 描述 API 操作的元数据信息。常用于 controller 层的方法上 ​ 3.Parameter 用于描述 API 操作中的参数 ​ 4.Operation Parameters ​ 5.Schema用于…

R语言实现——网状 Meta 分析

近来年&#xff0c;网状 Meta 分析相关研究不断涌现&#xff0c;此类研究不但能发表在国内各大核心期刊上&#xff0c;还能在SCI期刊甚至医学4大刊上看到其身影。随手在pubmed上面一搜索&#xff0c;就能得到一万多篇相关文献。俨然成为医学文献研究的“大杀器”&#xff01; P…

智慧公厕,让数据和技术更好服务社会生活

智慧公厕&#xff0c;作为智慧城市建设中不可忽视的一部分&#xff0c;正逐渐受到越来越多人的关注。随着科技的不断进步&#xff0c;智能化公厕已经成为一种趋势&#xff0c;通过数据的流转和技术的整合&#xff0c;为社会生活带来了更好的服务。本文以智慧公厕源头实力厂家广…

selenium元素定位--xpath定位--层级与逻辑组合定位

其他元素非唯一时&#xff0c;又不想用xpath绝对定位时&#xff0c;需要用到层级与逻辑定位. 一、层级属性结合定位&#xff1a; 遇到元素没有class、name、id等或属性动态变化情况时&#xff0c;可以找父节点元素&#xff0c;父级节点没有id时&#xff0c;可以继续往上找id&…

Flutter(踩坑)之Android sdkmanager tool not found

D:\Flutter\flutter\bin\flutter.bat doctor --verbose [√] Flutter (Channel stable, v1.2.1, on Microsoft Windows [Version 10.0.22631.3296], locale zh-CN)• Flutter version 1.2.1 at D:\Flutter\flutter• Framework revision 8661d8aecd (5 years ago), 2019-02-14 …

[leetcode]118.杨辉三角

前言&#xff1a;剑指offer刷题系列 问题&#xff1a; 给定一个非负整数 *numRows&#xff0c;*生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例&#xff1a; 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,…

【ZigBee/ZStack快速入门】04-串口

时钟 协议栈都是用的32M晶振工作的&#xff0c;所以在学习串口使用之前&#xff0c;应该学习一下如何调时钟 cc2530在运行过程中需要一个高频时钟信号和一个低频时钟信号&#xff0c;高频时钟信号主要供给cpu保证程序运行&#xff0c;16Mhz RC(这也是为什么定时器计算分频时是…

GPU-CPU-ARM-X86-RISC-CUDA

CPU更适合处理复杂逻辑运算和单线程任务&#xff0c;而GPU则更适合处理大规模并行计算任务。 CPU&#xff08;中央处理器&#xff09;通常具有较少的核心数量&#xff08;一般在2到16个之间&#xff09;&#xff0c;但每个核心的性能较强&#xff0c;擅长执行复杂的运算和逻辑…

DevSecOps平台架构系列-亚马逊云AWS DevSecOps平台架构

目录 一、概述 二、AWS DevSecOps实施原则 2.1 尽早采用安全测试&#xff0c;加速问题反馈 2.2 优先考虑预防性安全控制 2.3 部署检测性安全控制时&#xff0c;确保有与之互补的响应性安全控制 2.4 安全自动化 2.5 总结 三、AWS DevSecOps关键组件 3.1 关键组件 3.2 关…

LeetCode Python - 78. 子集

目录 题目描述解法方法一&#xff1a;DFS(回溯)方法二&#xff1a;二进制枚举 运行结果方法一方法二 题目描述 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的 子集 &#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任…

视频声音生成字幕 pr生成视频字幕 以及字幕乱码的解决

目录 目录 1、首先把要生成字幕的视频拖入以创建序列 2、点击工具栏的 窗口 选择 文本 3、选择字幕下的 转录序列 4、选择输出的语言&#xff08;主要看视频声音说的是啥语言&#xff09; 5、音轨 选择 音频1​编辑 6、点击转录 7、等待转录文本 8、点击创建说明性字幕按…

智慧交通(代码实现案例)

1.项目简介 目标: 了解智慧交通项目的架构知道智慧交通项目中的模块能够完成智慧交通项目的环境搭建 该项目是智慧交通项目&#xff0c;通过该项目掌握计算机视觉的方法在交通领域的相关应用&#xff0c;包括车道线检测的方法&#xff0c;多目标车辆追踪及流量统计方法&#…

如何快速进行城市内涝模拟?HTWATER软件

原文链接&#xff1a;如何快速进行城市内涝模拟&#xff1f;HTWATER软件https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247599079&idx2&sndc6f3da8b17c5587cf5b7766e7019729&chksmfa820200cdf58b16658983ecfbf2b369bff39813302942d6f7eb7b71428c68da71…

Django 仿博客园练习

数据库搭建 部分功能介绍 【一】注册 &#xff08;1&#xff09;效果显示、简单简介 主要亮点 结合了layui和forms组件默认头像可以随着性别的选择发生改变自定义头像可以实时更新显示forms组件报错信息可以局部刷新显示在对应框体下面 没有直接使用layui的前端验证后端验证…

Vue2 使用mockjs

一、创建项目 vue create mock-demo二、安装 npm install mockjs --save-dev npm install axios --save三、创建mock文件夹 四、修改main.js 五、应用

js选择语句

文章目录 1. if 分支语句1.1. 示例代码1.2. 运行结果 2. if 双分支语句3. if 多分支语句4. switch 语句&#xff08;了解&#xff09;4.1. 注意4.2. case 穿透现象4.3. case 穿透产生的原因 5. switch 语句与选择语句区别别5.1. 语法上的区别5.2. 应用场景上的区别 6. 三元表达…

HCIP—BGP路由发布

R1和R2&#xff0c;R4和R5建立EBGP对等体 R1和R2&#xff08;R4和R5&#xff09;之间属于EBGP对等体&#xff0c;可以使用直连物理接口建立对等体关系&#xff0c;TTL值默认1。由于使用直连物理接口方式建立&#xff0c;刚好一跳到达。 [R1]bgp 100 [R1-bgp]router-i…

燃气官网安全运行监测系统-阀井燃气监测仪-旭华智能

近年来&#xff0c;燃气爆炸事故频发&#xff0c;造成了重大人员伤亡和财产损失。这也再次为我们敲响警钟&#xff0c;燃气是我们日常生活中不可或缺的能源&#xff0c;但其潜在的危险性也是不容小觑。因此在重要节点加装燃气阀井气体监测仪&#xff0c;并将数据上传到系统平台…