• SpringBoot (3) Profiles,外部化配置,自定义starter


    目录

    1 Profiles

    1.1 "组件"环境隔离

    1.1.1 标识环境

    1.1.2 激活环境

    1.2 "配置"环境隔离

    1.2.1 添加"副配置文件"

    1.2.2 激活环境

    2 外部化配置

    2.1 配置优先级

    2.2 快速部署

    3 自定义starter

    3.1 parent模块

    3.2 基本抽取

    3.2.1 导yaml提示包

    3.2.2 【公共模块】抽取

    3.2.3 【普通模块】引用

    3.3 @EnableXxx注解抽取

    3.4 自动配置抽取

    3.4.1 SPI机制

    3.4.2 全自动配置

    3.5 注意事项


    1 Profiles

    用于"环境隔离",能够快速切换开发环境(dev),测试环境(test),生产环境(prod)等

    1.1 "组件"环境隔离

    针对不同的环境,往SpringIOC容器中注册不同的组件

    1.1.1 标识环境

            @Profile({"dev","test"})注解可以配合@Component等注解使用,也可以配合@Bean注解使用,标记当前组件在指定环境下生效

            没有标@Profile的类,在任何环境下都生效

            @Profile对于@EnableConfigurationProperties({Dog.class,Cat.class})中的Dog类、Cat类不生效(即Dog类用了@Profile也会被注册进SpirngIOC)

    1.1.2 激活环境

            在properties.yaml文件中激活对应的环境,如果没有配置对应的"激活环境",则SpringBoot默认激活default环境; 如果配置了"激活环境",则default环境失效

    1. spring:
    2. profiles:
    3. active: dev,test

    1.2 "配置"环境隔离

    针对不同的环境,选择生效的"副配置文件"(主配置文件application.yaml永远生效)

    1.2.1 添加"副配置文件"

            例如:application-dev.yamlapplication-test.yamlapplication-prod.yaml

    1.2.2 激活环境

            激活方式与1.1.2相同,且只能写在主配置文件中:

                    例如:spring.profiles.active=dev,则application-dev.yaml生效

            如果"副配置文件"和"主配置文件"配置冲突,以"副配置文件"为准

    2 外部化配置

    2.1 配置优先级

            命令行 > 包内外  (例: java -jar demo.jar --server.port=9999)

            jar包外配置优先级 > jar包内配置优先级

            副配置优先级 > 主配置优先级

    1. 包内:(1)application.yaml #server.port=8000
    2. (2)application-dev.yaml #server.port=8001
    3. 包外:(3)application.yaml #server.port=9000
    4. (4)application-dev.yaml #server.port=9001
    5. //有(1),以(1)为准
    6. //有(1)(2),以(2)为准
    7. //有(1)(2)(3),以(2)为准
    8. //有(1)(2)(3)(4),以(4)为准
    9. //执行的是命令行,以命令行为准

    2.2 快速部署

            根据"配置优先级"的规则,当需要修改某一项配置,无需再重新打jar包部署,而只需要新建一个与jar包文件同级别的"外部配置文件",然后用java -jar命令再次执行jar包即可

    3 自定义starter

            当我们在编写多个模块时,往往有许多重复代码,可以考虑将这些重复代码抽取出来作为一个starter,然后让模块去引用此starter即可

    3.1 parent模块

            新建一个parent父模块管理众多子模块,此模块只有一个pom.xml(打包方式为pom)文件,用于引入spring-boot-starter-parent和各种依赖(这样子模块就无需再引入了)

    3.2 基本抽取

    3.2.1 导yaml提示包

            在yaml中配置SpringBoot官方给的配置,当输入相关值的时候,会有提示

            而一些自定义的配置(例如:属性绑定时),则在yaml文件中不会有提示,而且被属性绑定的类还会被IDEA标红提示

            只需要引入spring提供的starter即可解决

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-configuration-processorartifactId>
    4. <optional>trueoptional>
    5. dependency>

    3.2.2 【公共模块】抽取

            (1) 创建公共模块,可以起名为xxx-xxx-spring-boot-starter

            (2) 抽取公共代码

            (3) 因为SpringBoot默认只会扫描自己主程序的包,外部引入的依赖包不会被扫描到,所以:

                    在【公共模块】的Spring配置类中,用@import或@Bean引入需要注册的组件(如Controller,Service,pojo等)

                    在【普通模块】引入【公共模块】后,在Spring配置类中用@Import或@Bean引入【公共模块】的Spring配置类

    1. //【自动配置类】
    2. @SpringBootConfiguration
    3. @ComponentScan("starter.xyz.aboluo")
    4. //因为这些类在【普通模块】中不会被扫描到,所以全部引入到Spring配置类中
    5. @Import({HelloController.class, HelloServiceImpl.class})
    6. @EnableConfigurationProperties({Hello.class})
    7. public class AboluoHelloAutoConfiguration {
    8. }
    9. //【配置属性类】
    10. //@Component 因为在Spring配置类中被用@EnableConfigurationProperties引入了,此注解可以不写
    11. @ConfigurationProperties(prefix = "hello")
    12. public class HelloProperties {
    13. private String welcomeMessage;
    14. private String companyName;
    15. }

    3.2.3 【普通模块】引用

    1. //【普通模块】的Spring配置类中用@Import引入【公共模块】的Spring配置类
    2. @SpringBootConfiguration
    3. @MapperScan("xyz.aboluo.dao")
    4. @Import(AboluoHelloAutoConfiguration.class)
    5. public class SpringConfig {
    6. }
    7. // 在yaml中对Hello类进行"属性绑定"
    8. hello:
    9. welcome-message: 欢迎您的使用!
    10. company-name: 字节跳动
    11. //此时依赖【公共模块】的【普通模块】启动后,就可以访问到"问候接口/hello/welcome"

    3.3 @EnableXxx注解抽取

            使用3.1的抽取方式的弊端:【普通模块】引入【公共模块】后,需要在Spring配置类上用@Import引入【公共模块】的Spring配置类

            利用Enable机制,可以在【公共模块】中自定义一个@EnableXxx注解,【普通模块】在Spring配置类使用【公共模块】的自定义注解即可,无需再使用@Import了

    1. //【公共模块】自定义注解
    2. @Retention(RetentionPolicy.RUNTIME)
    3. @Target({ElementType.TYPE})
    4. @Documented
    5. @Import({HelloController.class, HelloServiceImpl.class, Hello.class})
    6. public @interface EnableHello {
    7. }
    8. //【普通模块】的Spring配置类上使用"自定义注解"
    9. @SpringBootConfiguration
    10. @MapperScan("xyz.aboluo.dao")
    11. @EnableHello
    12. public class SpringConfig {
    13. }

    3.4 自动配置抽取

    3.4.1 SPI机制

            (Java的SPI默认访问META-INF/services/目录下的文件)

            (SpringBoot的SPI默认访问META-INF/spring/目录下的文件)

            项目引入官方starter依赖时,这个starter会继续依赖spring-boot-starter,其中一个核心依赖是spring-boot-autoconfigure,此时SpirngBoot会触发一个行为,自动去找org.springframework.boot:spring-boot-autoconfigureMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件

            此文件中所有的类(自动配置类一般写为XxxAutoConfiguration)会在项目启动时自动加载(被注册进SpringIOC),主要作用就是向SpringIOC容器中添加一些组件(用@Import或@Bean的方式)

            并且会用@EnableConfigurationProperties指定对应的配置属性类,开启属性绑定

    3.4.2 全自动配置

            使用3.2的抽取方式,还需要在【普通模块】的Spring配置类写"自定义注解",有没有可能连自定义注解也不用写,直接引入【公共模块】就可以用呢?

            利用SPI机制,在【公共模块】"类资源文件夹"resource下放META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,并写入Spring配置类(主要是要其中的@Import)的全限定类名

    1. //新建resource/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件
    2. starter.xyz.aboluo.boot.AboluoHelloAutoConfiguration
    3. @SpringBootConfiguration
    4. @ComponentScan("starter.xyz.aboluo")
    5. @Import({HelloController.class, HelloServiceImpl.class})
    6. @EnableConfigurationProperties({HelloProperties.class})
    7. public class AboluoHelloAutoConfiguration {
    8. }

    3.5 注意事项

            parent工程下的B工程依赖A工程,如果在给B工程package时,出现"Failed to collect dependencies at ...",需要parent工程进行install后即可

  • 相关阅读:
    Postman的高级用法一:重新认识postman核心模块
    git 分支管理进阶
    C#中数组与列表,集合等的联系
    tailwindcss 一览表
    【建议收藏】职场人口头和书面沟通必备词语,瞬间高大上
    NSA SELinux将在Linux 6.6中去品牌化为SELinux
    电子学会Python二级知识点(自己整理)
    开源3D激光(视觉)SLAM算法汇总(持续更新)
    python笔记之面向对象
    嵌入式开发:从C语言成功过渡的3个技巧
  • 原文地址:https://blog.csdn.net/SunnerChen/article/details/133875200