• SpringBoot3基础特性


    SpringBoot3基础特性

    SpringApplication

    自定义banner

    banner.png

    • 类路径添加banner.txt或设置spring.banner.location就可以定制banner
    • 推荐网站:Spring Boot banner在线生成工具,制作下载英文banner.txt,修改替换banner.txt文字实现自定义。

    提示:
    可以通过修改配置文件application.properties配置文件来关闭banner。

    spring.main.banner-mode=off
    
    • 1

    自定义SpringApplication

    @SpringBootApplication
    public class Boot311Application {
    
        public static void main(String[] args) {
            //SpringApplication:Boot应用的核心API入口
           //SpringApplication.run(Boot311Application.class, args);
            
            //1、自定义SpringApplication的底层设置
            SpringApplication springApplication = new SpringApplication(Boot311Application.class);
            
            //调整SpringApplication的参数
            //和配置文件设置冲突时,会优先配置文件
            springApplication.setBannerMode(Banner.Mode.CONSOLE);
            
            //2、SpringApplication运行
            springApplication.run(args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    FluentBuilder API

    //Builder方式构造SpringApplication
    new SpringApplicationBuilder()
            .main(Boot311Application.class)
            .bannerMode(Banner.Mode.CONSOLE)
            .sources(Boot311Application.class)
            .run(args);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Profiles

    环境隔离能力,快速切换开发、测试、生产环境

    实现步骤

    • 标识环境:指定哪些组件、配置在什么时候生效
    • 切换环境:这个环境对应的所有组件和配置就应该生效
    ①、指定环境

    Spring Profiles提供一种隔离配置的方式,使其仅在特定环境生效,任何@Component,@Configuration或@ConfigurationProperties可以使用@Profile标记,来指定何时被加载(容器中的组件都可以被@Profile标记)。

    ②、环境激活

    使用修改配置文件application.properties方式激活。

    spring.profiles.active=dev,test
    
    • 1
    测试

    创建四个组件Cat、Dog、Pig和Sheep。

    Cat

    @Data
    @Component
    @Profile({"dev", "test"})
    public class Cat {
        private String name;
        private String color;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Dog

    @Component
    @Data
    @Profile("test")
    public class Dog {
        private String name;
        private String age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Pig

    @Component
    @Data
    @Profile({"prod"})
    public class Pig {
        private Integer id;
        private String name;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Sheep

    @Component
    @Data
    public class Sheep {
        private Long id;
        private String name;
        private Integer age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    测试及结果

    @Slf4j
    @SpringBootApplication
    public class Boot311Application {
    
        public static void main(String[] args) {
            //Builder方式构造SpringApplication
            ConfigurableApplicationContext context = new SpringApplicationBuilder()
                    .main(Boot311Application.class)
                    .bannerMode(Banner.Mode.CONSOLE)
                    .sources(Boot311Application.class)
                    .run(args);
    
            try {
                //由于在没有找到的情况下会抛异常
                Cat cat = context.getBean(Cat.class);
                log.info("组件cat:{}", cat);
            }catch (Exception e){
    
            }
    
            try {
                Dog dog = context.getBean(Dog.class);
                log.info("组件dog:{}", dog);
            }catch (Exception e){
    
            }
    
            try {
                Pig pig = context.getBean(Pig.class);
                log.info("组件pig:{}", pig);
            }catch (Exception e){
    
            }
    
            try {
                Sheep sheep = context.getBean(Sheep.class);
                log.info("组件sheep:{}", sheep);
            }catch (Exception e){
    
            }
        }
    }
    
    /**
     * 1、标识环境
     *      1) dev(开发环境)、test(测试环境)、prod(生产环境)、default(在没有设置激活时会生效,但设置激活不是default时不会生效)
     *          组件没有标注@Profile代表任意时候都生效
     *      2) 指定每个组件在哪个环境下生效
     *          @Profile({"dev", "test"})
     *      3) 默认只有激活指定环境,这些组件才会生效
     *  结果;组件sheep:Sheep(id=null, name=null, age=null)
     * 2、激活环境
     *      1)使用配置文件:spring.profiles.active=dev,test
     *          结果:
     *              组件cat:Cat(name=null, color=null)
     *              组件dog:Dog{name='null', age='null'}
     *              组件sheep:Sheep(id=null, name=null, age=null)
     *      2)命令行激活:java -jar xxx.jar --spring.profile.active=dev
     */ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    ③、环境包含

    Spring.profiles.active和spring.profiles.default属性用于配置和激活不同环境下的配置文件。通常情况下,这些属性应该在专门用于配置环境的文件中进行设置,而不是在application-dev.yaml这样的具体环境文件中。也可以额外添加生效文件(表示不管激活哪个环境,这个包含的环境都要有。即总是要生效的环境。),而不是激活文件。比如:

    spring.profiles.include[0]=common
    spring.profiles.include[1]=local
    
    • 1
    • 2
    总结:

    生效的环境 = 激活的环境 + 默认环境(没有添加@Profile) + 包含的环境.
    项目中使用:
    基础的配置:mybatis、log…:写到(include)包含环境中
    需要动态切换变换的环境:db、redis:写到激活环境,可以使用spring.profiles.group.xxx=dev, test进行分组,只需要激活xxx就可以将分组中的内容全部激活。

    Profile配置文件

    • application-{profile}.properties可以作为指定环境的配置文件。
    • 激活这个环境,配置就会生效。最终生效的所有配置是:

    application.properties:主配置文件,任意时候都生效
    application-{profile}.properties:指定环境配置文件,激活指定环境生效。
    Profile配置文件.png
    例如:

    在application.properties文件中添加配置。

    spring.profiles.active=dev
    
    • 1

    表示在激活dev环境的时候配置文件application-dev.properties生效。

    注意:
    ①、当激活的配置文件内容和主配置文件冲突时,以激活的为主。
    ②、项目的所有生效配置项 = 激活环境配置文件的所有项 + 主配置文件不冲突的所有项

    多环境并发控制

    除了SpringBoot外很多的构建工具都有多环境的情况,如:Maven、SpringBoot,如果两者都配置并且它们的环境不同,应该以先加载的环境为主。

    a、当maven与SpringBoot同时对多环境进行控制时,以Mven为主,SpringBoot使用@maven中activ标签名称@占位符读取Maven对应的配置属性
    b、基于SpringBoot读取Maven配置属性的前提下,如果在Idea下测试工程时,pom.xml每次更新需要手动compile方可生效。
    示例:

    在pom.xml中,我们可以使用Maven的profiles来定义这些不同的环境配置。

    <profiles>
      <profile>
        <id>devid>
        <properties>
          <db.url>jdbc:mysql://localhost:3306/dev_dbdb.url>
          <db.username>dev_userdb.username>
          <db.password>dev_passworddb.password>
        properties>
      profile>
      <profile>
        <id>prodid>
        <properties>
          <db.url>jdbc:mysql://localhost:3306/prod_dbdb.url>
          <db.username>prod_userdb.username>
          <db.password>prod_passworddb.password>
        properties>
      profile>
    profiles>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在Spring Boot的配置文件application.properties中,使用@maven注解来读取Maven配置文件中定义的属性。

    spring.datasource.url=@maven.db.url@
    spring.datasource.username=@maven.db.username@
    spring.datasource.password=@maven.db.password@
    
    • 1
    • 2
    • 3

    外部化配置

    场景:线上应用如何快速修改配置,并应用最新配置?

    • SpringBoot使用配置优先级 + 外部配置简化配置、简化运维
    • 只需要给jar应用所的文件夹放一个application.properties最新配置文件,重启项目就能自动应用最新配置。

    配置优先级

    SpringBoot允许将配置外部化,以便可以在不同的环境中使用相同的应用程序代码。我们可以使用各种外部配置源,包括Java Properties文件,YAML文件、环境变量和命令行参数。@Value可以获取值,也可以用@ConfiguraionProperties将所有属性绑定到java object中。

    以下是SpringBoot属性源加载顺序(优先级由低到高,高优先级配置会覆盖低优先级。),后面的会覆盖前面的值。

    • 默认属性( spring.application.setDefaultProperties指定)
    • @PropertySource指定加载的配置(需要写在@Configuration类上才生效)
    • 配置文件(application.properties/yaml等)
    • RandomValuePropertySource支持的random.*配置(如:@Value(“${random.int}”))
    • OS环境变量
    • Java系统属性(来自System.Properties())
    • JNDI属性(来自java:comp/env)
    • ServletContext初始化参数
    • ServletConfig初始化参数
    • SPRING_APPLICATION_JSON属性(内置在环境变量或系统属性中的JSON)
    • 命令行参数
    • 测试属性。(@SpringBootTest进行测试时指定的属性)
    • 测试类@TestPropertySource注解
    • Devtoos设置的全局属性。($HOME/.config/spring-boot)

    结论:
    配置可以写道很多位置,常见的优先级顺序:命令行>配置文件>springapplication配置

    配置文件优先级如下(从低到高):

    • jar包内的application.properties/yaml
    • jar包内的application-{profile}.properties/yaml
    • jar包外的application.propeterties/yaml
    • jar包外的application-{profile}.properties/yaml

    结论:包外>包内
    建议:
    ①、使用一种格式的配置文件,如果.properties和.yaml同时存在,则.properties优先。
    ②、所有参数均可由命令行传入,使用–参数项=参数值,例如:–property=value,将会被添加到环境变量中,并优先于配置文件,比如java -jar app.jar --name = “spring”,可以使用@Value(“${name}”)获取。

    外部配置

    SpringBoot应用启动时会自动寻找application.properties和application.yaml位置进行加载。优先级从低到高如下:

    类路径(内部)

    • 类根路径
    • 类下/config包

    当前路径(项目所在的位置,外部)

    • 当前路径
    • 当前/config子目录
    • /config目录的直接子目录

    优先级.png

    总结

    • 命令行>所有
    • 包外>包内
    • config目录>根目录
    • profile>application

    配置不同就都生效(部署),配置相同高优先级覆盖低优先级。

    导入配置

    在配置文件中使用如下配置:

    spring.config.import=classpath:/xxx.properties
    
    • 1

    它和使用@PropertySource效果相同。

    注意:配置文件的优先级高于导入配置的优先级。

    属性占位符

    配置文件中可以使用${name:default}形式取出之前配置过的值

    app.name=MyApp
    app.description = ${app.name}是我的名字
    
    • 1
    • 2

    示例:

    application.properties

    hello.test= this is my test
    
    • 1

    控制器

    @RestController
    public class HelloController {
        @Value("${hello.test:1433223}")
        String test;
    
        @GetMapping("/hello")
        public String test(){
            return test;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    取值.png

    单元测试-JUnit5

    整合

    SpringBoot提供一系列测试工具及注解方便我们进行测试。

    spring-boot-test提供核心测试能力,spring-boot-test-autoconfigure提供测试的一些自动配置。只需要导入spring-boot-starter-test即可整合测试。

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-testartifactId>
        <scope>testscope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    spring-boot-starter-test默认提供的测试库有:JUnit5、Spring Test、AssertJ、Hamcrest、Mockito、JSONassert、JsonPath

    测试
    组件测试

    直接使用@Autowired容器中的组件进行测试

    示例

    创建HelloService

    @Service
    public class HelloService {
        public int sum(int a, int b){
            return a+b;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在测试类中测试

    //测试类也必须在主程序所在的包及其子包
    @SpringBootTest//具备测试SpringBoot应用容器中所有组件的功能
    class Boot311ApplicationTests {
        //测试方法
        @Autowired//自动注入任意组件即可测试
        HelloService helloService;
    
        @Test
        void contextLoads() {
            int sum = helloService.sum(2, 5);
            System.out.println("sum = " + sum);
        }
        /*sum = 7*/
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    注解

    JUnit5的注解与JUnit4注解有所变化
    官方文档
    junit5.png

    参数化测试:

    使得用不同的参数多次运行测试成为了可能,为单元测试带来了便利。
    利用@ValueSource等注解,指定入参, 可以使用不同的参数进行多次单元测试,而不需要每新增一个参数就新增一个单元测试,减少了代码冗余。

    @ValueSource #为参数化测试制定了入参来源,支持八大基本类型以及String类型和Class类型。
    @NullSource #表示为参数化测试提供一个null得入参
    @EnumSource #表示为参数化测试提供一个枚举入参
    @CsvFileSource #表示读取指定CSV文件内容作为参数化测试入参
    @MethodSource #表示读取指定方法的返回值作为参数化限额是入参(方法返回需要是一个流)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    示例
    @ParameterizedTest
    @ValueSource(strings = {"one", "two", "three"})
    @DisplayName("参数化测试")
    public void parameterizedTest1(String string){
        System.out.println(string);
        //使用断言方式
        Assertions.assertTrue(StringUtils.isNotBlank(string));
    }
    /*
    * one
      two
      three
    * */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    华为OD机试 - 跳格子游戏 - 深度优先搜索dfs算法(Java 2023 B卷 200分)
    【云原生】-Docker部署及使用压测神器sysbench
    Spring Cloud Gateway 服务网关的部署与使用详细介绍
    mybatis学习(7):Windows下安装MySQL详细教程
    Python内置函数系统学习(1)——数据转换与计算 (详细语法参考+参数说明+应用场景示例) 对象--->>字符串、字符--->>ASACII码 综合应用
    【比较mybatis、lazy、sqltoy、mybatis-flex操作数据】操作批量新增、分页查询(二)
    SpringBoot 整合【MybatisPlus、Shiro】实现权限认证信息
    基于start.spring.io,定制你的Java脚手架
    SpringBoot接口防抖(防重复提交)
    信息系统项目管理师---第七章 项目成本管理
  • 原文地址:https://blog.csdn.net/xry12354/article/details/134384118