Maven的porfile与SpringBoot的profile结合使用完成多环境配置文件切换 详解
一.Maven的porfile
首先弄清楚Maven的profile
1.pom.xml增加多环境配置
<!-- 多环境配置 start -->
<profiles>
<!-- local一般作为开发者开发的环境 -->
<profile>
<id>sxdlocal</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sxdProfileActive>local</sxdProfileActive>
</properties>
</profile>
<!-- dev一般作为开发者稳定的自测环境 -->
<profile>
<id>dev</id>
<properties>
<sxdProfileActive>dev</sxdProfileActive>
</properties>
</profile>
<!-- uat环境一般作为业务验收环境 -->
<profile>
<id>uat</id>
<properties>
<sxdProfileActive>uat</sxdProfileActive>
</properties>
</profile>
<!-- test环境作为测试环境 -->
<profile>
<id>test</id>
<properties>
<sxdProfileActive>test</sxdProfileActive>
</properties>
</profile>
<!-- online环境作为生产环境 -->
<profile>
<id>online</id>
<properties>
<sxdProfileActive>online</sxdProfileActive>
</properties>
</profile>
<!-- backUp作为 2021.07.23分环境之前的一个备份稳定配置 -->
<profile>
<id>myBackUp</id>
<properties>
<sxdProfileActive>backup</sxdProfileActive>
</properties>
</profile>
</profiles>
<!-- 多环境配置 end -->
官网地址属性说明:https://maven.apache.org/ref/3.8.1/maven-model/maven.html#class_activation
说明:
<profiles> //包含多种profile <profile> //可以基于环境参数 或 命令行参数中 指定的ID 激活的构建过程的修改 <id>sxdlocal</id> //IDEA的MAVEN组件中展示的profile值 或 命令行中 -P后指定的profile值 <activation> //激活标签 <activeByDefault>true</activeByDefault> //默认激活该profile对应的配置文件,如果命令行-P指定了 或 IDEA勾选了,则以实际指定或勾选的为准 </activation> <properties> //属性标签 内部包含<key>value</key> key是可以自己指定的 <sxdProfileActive>local</sxdProfileActive> </properties> </profile> </profiles>
2.build标签中的resource标签的filtering属性一定要设置为true
<!-- build标签描述了如何来编译及打包项目 参考地址:https://blog.csdn.net/u010010606/article/details/79727438 --> <build> <!-- 而具体的编译和打包工作是通过build中配置的 plugin 来完成 --> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <version>2.6</version> <artifactId>maven-resources-plugin</artifactId> <configuration> <encoding>UTF-8</encoding> <nonFilteredFileExtensions> <nonFilteredFileExtension>xlsx</nonFilteredFileExtension> </nonFilteredFileExtensions> </configuration> </plugin> </plugins> <!-- build过程中涉及的资源文件 用于包含 或 排除某些资源文件 --> <resources> <resource> <!-- 资源文件的路径,默认位于${basedir}/src/main/resources/目录下 --> <directory>src/main/resources</directory> <filtering>true</filtering> <!-- 一组文件名的匹配模式,被匹配的资源文件将被构建过程忽略。同时被includes和excludes匹配的资源文件,将被忽略。 --> <excludes> <exclude>**/*.ttf</exclude> <exclude>**/*.woff</exclude> </excludes> </resource> </resources> </build>
为什么一定要设置为 true ??下面通过作用阐明 和 举例子解释
2.1 filtering标签的作用
官网说明地址:https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
filtering作用即 设置为true代表打通pom.xml和 <directory>指定路径下的文件之间的通道。(该目录下一般都是配置文件yml或properties,也可以是txt等其他)
解析第一种:使得<directory>指定路径下的配置文件中以${}表达式定义的变量,可以从pom.xml文件中获取到对应标签变量去完成文本替换。
解析第二种:或者替换<directory>指定路径下的配置文件中以@sxdProfileActive@表达式定义的变量
2.2 ${}表达式替换 举例
使得<directory>指定路径下的配置文件中以${}表达式定义的变量,可以从pom.xml文件中获取到对应标签变量去完成文本替换。
例如:
pom.xml文件中定义了标签
<name>张三</name>
配置文件(properties/yml/txt/...等所有在<directory>指定路径下的文件)中定义
spring.myname=${name}
则maven编译完成后,配置文件中的结果为
spring.myname=张三
2.3 @xxx@表达式 举例
或者替换<directory>指定路径下的配置文件中以@sxdProfileActive@表达式定义的变量
例如:
pom.xml文件中定义了
<profile> <id>dev</id> <properties> <sxdProfileActive>dev</sxdProfileActive> </properties> </profile>
application.properties文件中定义的
spring.profiles.active=@sxdProfileActive@
则maven编译完成后,application.properties配置文件中的结果为
spring.profiles.active=dev
2.4 如果filtering就设置为false,表现会是怎样
所以,多环境profile切换配置文件情况下,该标签必须设置为true,否则拿上面第二个例子看,就会导致
spring.profiles.active=@sxdProfileActive@
不能完成正常的值替换,
从而导致applocation-{profile}.properties匹配不到对应的profile的配置文件,
从而默认加载application.properties主配置文件。
而主配置文件中毛配置都没有,(下面的Springboot 的 profile会把多环境的配置文件内容贴出来,以下面贴出来为例)
最终导致 java代码中的@Bean/@Configuration 中用到配置文件中的配置才能完成初始化的动作 就会失败。
例如:
java代码初始化这样的一个Configuration
@Configuration public class DruidDBConfig { @Value("${spring.datasource.url}") private String dbUrl; ...... }
,如果设置为false,最终表现便是 启动时 报错如下:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'druidDBConfig':
Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.url' in value "${spring.datasource.url}"
3.pom.xml增加多环境配置后 IDEA Maven显示的Profiles即已增加的多环境配置显示
4.Maven的命令查看 mvn -P代表的含义
mvn --help
-P即 代表
mvn --activate-profiles dev
5.所以,Maven的profile怎么生效
5.1 本地
即可通过 IDEA Maven显示的Profiles 的切换勾选,完成maven 的 profiles.active 的值切换
勾选,即以勾选的生效profile,全不勾选,则以pom.xml多环境配置中设置了
<activeByDefault>true</activeByDefault>
的生效profile
5.2 test/online服务器端
可以配置maven打包命令 -P 指明profiles.active
如下,指定生效的profile为 pom.xml文件中 ID = test的profile生效。
mvn clean package install -P test -Dmaven.test.skip=true -U
同理,如果未设置 -P,则默认以pom.xml多环境配置中设置了
<activeByDefault>true</activeByDefault>
的生效profile
二.SpringBoot的profile
1.如果不和maven的profile联动,正常SpringBoot切换profile完成多环境配置切换,是什么样?
正常简陋原始一点,本机开发时候就在application.properties主配置文件写死
spring.profiles.active = local
上测试环境,就修改application.properties主配置文件
spring.profiles.active = test
上不同环境就得手动去变更。
2.Maven的profile 和 Spring boot的profile联动
Maven的profile 和 Spring boot的profile联动,达到开发一次,多环境自动编译时加载并生效不同profile对应的配置文件的效果。
2.1 配置文件代码
application.properties
spring.profiles.active=@sxdProfileActive@
application-local.properties
server.port=9666 spring.jackson.time-zone=GMT+8 #spring boot2.0 限制文件上传大小【spring boot默认1MB】 spring.servlet.multipart.max-file-size=90MB spring.servlet.multipart.max-request-size=100MB #datasource 单数据源 spring.datasource.continue-on-error=false #=========本地=========== spring.datasource.url=jdbc:mysql://localhost:3306/swapping?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8 #=======虚拟机========== #spring.datasource.url=jdbc:mysql://192.168.92.130:3306/swapping?useSSL=false&useUnicode=true&characterEncoding=UTF-8 spring.datasource.username=root spring.datasource.password=mynewpassword123 #druid 下面为连接池的补充设置,应用到上面所有数据源中 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver # 初始化大小,最小,最大 spring.datasource.initialSize=5 spring.datasource.minIdle=5 spring.datasource.maxActive=20 # 配置获取连接等待超时的时间 spring.datasource.maxWait=60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 spring.datasource.timeBetweenEvictionRunsMillis=60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 spring.datasource.minEvictableIdleTimeMillis=300000 spring.datasource.validationQuery=SELECT 'x' spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=false # 打开PSCache,并且指定每个连接上PSCache的大小 spring.datasource.poolPreparedStatements=true spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 spring.datasource.maxOpenPreparedStatements=20 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 spring.datasource.filters=stat,wall,log4j # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 合并多个DruidDataSource的监控数据 #spring.datasource.useGlobalDataSourceStat=true #mybatis相关配置 参考地址:https://mybatis.org/mybatis-3/zh/index.html #mybatis映射文件的位置 mybatis.mapper-locations=classpath:mapper/*.xml #mybatis指定entity位置 mybatis.type-aliases-package=com.sxd.swapping.mybatis.pojo #mybatis展示sql语句执行 logging.level.com.sxd.swapping=debug #允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作 mybatis.configuration.use-generated-keys=true #是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn mybatis.configuration.map-underscore-to-camel-case=true #pagehelper mybatis分页插件 pagehelper.helperDialect=mysql pagehelper.reasonable=true pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql pagehelper.returnPageInfo=check #jpa相关配置 spring.jpa.database=mysql spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update spring.jpa.database-platform=org.hibernate.dialect.MySQL55Dialect #redis配置 # Redis数据库索引(默认为0) spring.redis.database=0 # Redis服务器地址 #======本地======= spring.redis.host=localhost #=======虚拟机======= #spring.redis.host=192.168.92.130 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password=398023 # 连接池最大连接数(使用负值表示没有限制) spring.redis.jedis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.jedi.pool.max-wait=-1 # 连接池中的最大空闲连接 spring.redis.jedi.pool.max-idle=8 # 连接池中的最小空闲连接 spring.redis.jedi.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.jedi.timeout=0 #elasticsearch相关配置 #es的cluster集群名称可以查看服务器安装的集群名称 curl http://192.168.92.130:9200 获取到集群名称 spring.data.elasticsearch.cluster-name=docker-cluster #注意端口为9300 9300 是 Java 客户端的端口,支持集群之间的通信。9200 是支持 Restful HTTP 的接口 spring.data.elasticsearch.cluster-nodes=192.168.92.130:9300 #logback对接logstash的日志配置文件 logging.config=classpath:logback-spring.xml #线程池配置 thread.pool.core.size=10 thread.pool.max.size=10 thread.pool.queue.capacity=10000 thread.pool.alive.seconds=1000
application-test.proerties
server.port=9669 spring.jackson.time-zone=GMT+8 #spring boot2.0 限制文件上传大小【spring boot默认1MB】 spring.servlet.multipart.max-file-size=90MB spring.servlet.multipart.max-request-size=100MB #datasource 单数据源 spring.datasource.continue-on-error=false #=========本地=========== spring.datasource.url=jdbc:mysql://localhost:3306/swapping?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8 #=======虚拟机========== #spring.datasource.url=jdbc:mysql://192.168.92.130:3306/swapping?useSSL=false&useUnicode=true&characterEncoding=UTF-8 spring.datasource.username=root spring.datasource.password=mynewpassword123 #druid 下面为连接池的补充设置,应用到上面所有数据源中 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver # 初始化大小,最小,最大 spring.datasource.initialSize=5 spring.datasource.minIdle=5 spring.datasource.maxActive=20 # 配置获取连接等待超时的时间 spring.datasource.maxWait=60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 spring.datasource.timeBetweenEvictionRunsMillis=60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 spring.datasource.minEvictableIdleTimeMillis=300000 spring.datasource.validationQuery=SELECT 'x' spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=false # 打开PSCache,并且指定每个连接上PSCache的大小 spring.datasource.poolPreparedStatements=true spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 spring.datasource.maxOpenPreparedStatements=20 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 spring.datasource.filters=stat,wall,log4j # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 合并多个DruidDataSource的监控数据 #spring.datasource.useGlobalDataSourceStat=true #mybatis相关配置 参考地址:https://mybatis.org/mybatis-3/zh/index.html #mybatis映射文件的位置 mybatis.mapper-locations=classpath:mapper/*.xml #mybatis指定entity位置 mybatis.type-aliases-package=com.sxd.swapping.mybatis.pojo #mybatis展示sql语句执行 logging.level.com.sxd.swapping=debug #允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作 mybatis.configuration.use-generated-keys=true #是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn mybatis.configuration.map-underscore-to-camel-case=true #pagehelper mybatis分页插件 pagehelper.helperDialect=mysql pagehelper.reasonable=true pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql pagehelper.returnPageInfo=check #jpa相关配置 spring.jpa.database=mysql spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update spring.jpa.database-platform=org.hibernate.dialect.MySQL55Dialect #redis配置 # Redis数据库索引(默认为0) spring.redis.database=0 # Redis服务器地址 #======本地======= spring.redis.host=localhost #=======虚拟机======= #spring.redis.host=192.168.92.130 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password=398023 # 连接池最大连接数(使用负值表示没有限制) spring.redis.jedis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.jedi.pool.max-wait=-1 # 连接池中的最大空闲连接 spring.redis.jedi.pool.max-idle=8 # 连接池中的最小空闲连接 spring.redis.jedi.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.jedi.timeout=0 #elasticsearch相关配置 #es的cluster集群名称可以查看服务器安装的集群名称 curl http://192.168.92.130:9200 获取到集群名称 spring.data.elasticsearch.cluster-name=docker-cluster #注意端口为9300 9300 是 Java 客户端的端口,支持集群之间的通信。9200 是支持 Restful HTTP 的接口 spring.data.elasticsearch.cluster-nodes=192.168.92.130:9300 #logback对接logstash的日志配置文件 logging.config=classpath:logback-spring.xml #线程池配置 thread.pool.core.size=10 thread.pool.max.size=10 thread.pool.queue.capacity=10000 thread.pool.alive.seconds=1000
各环境的配置文件,咱么就以不同端口号 区分一下,后面启动时候,选择不同maven的profile,则启动后加载勾选的proflie对应的properties文件
例如,勾选local
启动,则端口为
例如,勾选test
重新启动
2.2 联动的原理是啥呢?
①首选pom.xml配置了多环境配置
②IDEA指定勾选 和 服务器端 mvn -P test 指定maven的profile对应的ID
③服务启动/打包编译时候,便根据maven的profile对应的ID 找到对应的<profile>标签,并加载到了内部的<properties>标签
④此时,<build>标签中的<resources>中的<resource>下,<filtering>一定是设置为true,开启了pom和配置文件之间的通道
⑤然后将对应的<profile>标签中加载到的<properties>标签中的自定义key - value拿上,去找到application.properties中的@XXX@ 或 ${}表达式
⑥spring.profiles.active=@sxdProfileActive@,并根据key为sxdProfileActive,做了value的替换,最终编译完成,application.properties中的 spring.profiles.active=local
⑦如此,应用在启动中,就根据 spring.profiles.active=local,成功加载上了 application-local.properties 文件
⑧最终,完成了 maven的profile和 springboot的profile的联动替换。
====================
完。