springboot动态配置与动态打包

springboot 动态配置与动态打包

通常在开发环境和生产环境,我们的应用程序会需要很多动态配置信息,有的应用程序的jar包也需要根据不同环境来动态打包。

要实现两点核心功能:

  • 在pom.xml中根据环境配置变量,供Java代码或properties.xml中获取变量内容
  • maven打包时可动态指定环境编译出不同环境配置的app。

开始学习之前,您需要做如下准备 

  • springboot v2.3.6.RELEASE版本
  • JDK1.8
  • 一个好用的IDE。推荐使用Spring推出的STS项目工具来写demo,免费且占用内存小,另外一点可以参照本教程作对比,当然用IDEA也行。
  • STS下载:https://spring.io/tools/

快速创建一个springboot项目

这里我使用一个已经创建好的springboot项目做案例

项目结构如下:

简单介绍一下项目结构说明

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.3.6.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.lb</groupId>
	<artifactId>springboot-quickstart</artifactId>
	<version>1.0.0</version>
	<name>springboot-quickstart</name>
	<description>springboot-quickstart</description>

	<properties>
		<java.version>1.8</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<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>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

主应用程序


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import com.lb.springboot.config.AppConfig;

@SpringBootApplication
public class QuickstartApplication {
	
	/**
	 * 应用程序入口
	 * @param args
	 */
	public static void main(String[] args) {
		// 启动springboot应用程序
		ConfigurableApplicationContext context = SpringApplication.run(QuickstartApplication.class, args);
		// 测试自定义配置
		AppConfig appConfig = context.getBean(AppConfig.class);
		// 打印日志
		appConfig.output();
	}

}

自定义配置


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;


/**
 * 应用的自定义配置
 * @author lb
 *  <h2>说明</h2>
 *  <p> {@code @Configuration}的作用相当于引入web.xml --> applicationContext-web.xml --> ApplicationConfig.xml </p>
 *  <p> {@code @ComponentScan}的作用相当于applicationContext-web.xml 配置的扫描</p>
 *   <p> {@code @PropertySource}加载自定义的配置</p>
 *   
 */
@Configuration
@ComponentScan(basePackages = {"com.lb.springboot.*"})
@PropertySource("classpath:myconfig.properties")
public class AppConfig{
	
	private static final Logger LOGGER = LoggerFactory.getLogger(AppConfig.class);
	
	@Value("${applicationfile.coustom.testname}")
	private String coustomName;

	@Value("${coustomfile.username}")
	private String username;
	
	@Autowired
	private Environment env;
	
	public void output() {
		LOGGER.info("使用 @Value 读取到的自定义配置: {}", coustomName);
		LOGGER.info("使用 @Autowired Environment 读取到的自定义配置: {}", env.getProperty("applicationfile.coustom.testname"));
		LOGGER.info("加载自定义配置文件 - username: {},",username);
	}
}

测试controller


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(IndexController.class);
	
	@GetMapping(value = "index")
	public String index() {
		LOGGER.info("index is running...");
		return "Hello,Springboot !";
	}

}

应用主配置文件 application.properties

# 服务端口
server.port=8080
# 服务路径,配置此路径,请求API需要增加 /qs 再进行请求
server.servlet.context-path=/qs
# 自定义配置
applicationfile.coustom.testname=Tom 










自定义配置文件 myconfig.properties

coustomfile.username=jack

启动项目测试,在主程序上,鼠标右键 ---> Run As ---> 选择Java application 或者Springboot App  启动

启动成功后,控制台打印如下:

我们来测试一下服务可用性,在控制台terminal或者iterm2 curl localhost:8080/qs/index,结果如下:

好了,准备工作完毕。接下来我们开始修改pom.xml,让其支持spring动态配置及动态打包

动态配置&动态打包

一、修改pom.xml

1. 新增maven profile相关配置

这个配置在应用打包的时候,会动态将profile标签配置的properties打包到应用jar或war中

    <!-- profile配置切换. 使用maven命令: mvn clean install -P local ( dev 、 qa 、 pro ) -->
	<profiles>
		<!-- 开发环境配置 -->
		<profile>
			<id>dev</id>
			<activation>
				<!-- 设置本profile为默认配置,在进行Maven打包时不指定-P参数,使用 dev的配置进行打包 -->
				<activeByDefault>true</activeByDefault>
			</activation>
			<dependencies>
				<dependency>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-undertow</artifactId>
				</dependency>
			</dependencies>
			<properties>
				<!-- /src/main/resources/application.properties 中的配置-->
				<spring.profiles.active>dev</spring.profiles.active>
				<!-- 跟随环境变化的自定义参数 -->
				<lb.env.dynamic.attr>2020-12-12-dev</lb.env.dynamic.attr>
			</properties>
		</profile>
		<!-- 生产环境配置 -->
		<profile>
			<id>pro</id>
			<dependencies>
				<dependency>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-undertow</artifactId>
				</dependency>
			</dependencies>
			<properties>
				<spring.profiles.active>pro</spring.profiles.active>
				<!-- 动态参数 -->
				<lb.env.dynamic.attr>2020-12-15-pro</lb.env.dynamic.attr>
			</properties>
		</profile>
	</profiles>

1.2 修改build配置

我们会在build中增加如下几项maven插件

  • maven-compiler-plugin  (编译Java代码)
  • maven-resources-plugin (处理资源文件 )
  • maven-surefire-plugin (忽略测试用例)
  • maven-source-plugin (处理源代码)
    <build>
		<!-- 最终打出来的jar包名称 -->
		<finalName>lb-springboot-quickstart</finalName>
		<plugins>
			<!-- springboot的maven插件 -->
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<!-- 解决maven update project 后JDK版本降低为1.5的bug -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<!-- 打包时忽略单元测试文件,防止由于单元测试编写错误导致打包失败的情况 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<configuration>
					<skip>true</skip>
					<includes>
						<include>**/*Test*.java</include>
					</includes>
					<testFailureIgnore>true</testFailureIgnore>
				</configuration>
			</plugin>
			<!-- 需要对于Maven工程的源代码进行源文件的打包,可以利用source插件来完成,在install时,会同时将源码包安装到本地仓库 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-source-plugin</artifactId>
				<executions>
					<!-- 绑定到特定的生命周期之后,运行maven-source-pluin 运行目标为jar-no-fork -->
					<execution>
						<phase>package</phase>
						<goals>
							<goal>jar-no-fork</goal>
						</goals>
					</execution>
				</executions>
			</plugin>

			<!-- maven-resources-plugin用来处理资源文件 -->
			<!-- 利用此插件实现Maven动态打包: mvn clean install -P pro/dev/local -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-resources-plugin</artifactId>
				<executions>
					<execution>
						<id>default-resources</id>
						<phase>validate</phase>
						<!-- goals包含以下三种配置项:
						1. resources:resources,拷贝main resources到main output directory。它绑定了process-resources生命周期阶段,当执行Compiler:compile插件目标前就会执行此阶段。
    					2. resources:testResources,拷贝test resources到test output directory。它绑定了process-test-resources生命周期阶段,当执行surefire:test插件目标前就会执行此阶段。
    					3. resources:copy-resources,手动拷贝资源到输出目录 -->
						<goals>
							<goal>copy-resources</goal>
						</goals>
						<configuration>
							<outputDirectory>target/classes</outputDirectory>
							<useDefaultDelimiters>false</useDefaultDelimiters>
							<delimiters>
								<delimiter>$</delimiter>
							</delimiters>
							<resources>
								<!-- 打包时包含properties、xml 
								比如mybatis的mapper.xml文件,我们习惯把它和Mapper.java放一起,都在src/main/java下面,
								这样利用maven打包时,就需要修改pom.xml文件,来把mapper.xml文件一起打包进jar或者war -->
								<resource>
									<!-- 是否替换资源中的属性 -->
									<filtering>true</filtering>
									<directory>src/main/java</directory>
									<includes>
										<include>**/*.properties</include>
										<include>**/*.xml</include>
									</includes>
								</resource>
								<resource>
									<directory>src/main/resources/</directory>
									<filtering>true</filtering>
									<includes>
										<include>**/*.xml</include>
										<include>**/*.yml</include>
										<include>**/*.properties</include>
									</includes>
								</resource>
							</resources>
						</configuration>
					</execution>
				</executions>
			</plugin>

		</plugins>
	</build>

二、修改application.properties

在修改前,我们要知道一点,就是springboot启动时会自动加载以 application开头的配置文件,例如application-*.properties。 我们要在application.properties里新增 spring.profiles.active=$spring.profiles.active$配置项 为什么使用前后$符号来获取参数,是因为在/pom.xml文件中maven-resources-plugin插件指定的delimiter符号是$符号。

然后我们在src/main/resources目录下新增2个新的配置文件,文件名分别为:application-dev.properties 、application-pro.properties

application-dev.properties 内容如下:

# DEV服务端口
server.port=8081

application-pro.properties 内容如下:

# PRO服务端口
server.port=8082

myconfig.properties,新增如下配置

# pom.xml中自定义的环境变量 profiles--->profile--->properties配置
lb.env.dynamic.attr=$lb.env.dynamic.attr$

三、测试验证

接下来我们在程序中读取pom.xml的动态配置信息,在com.lb.springboot.config.AppConfig获取pom.xml中定义的配置

@Configuration
@ComponentScan(basePackages = {"com.lb.springboot.*"})
@PropertySource("classpath:myconfig.properties")
public class AppConfig{
	
	private static final Logger LOGGER = LoggerFactory.getLogger(AppConfig.class);
	
	@Value("${applicationfile.coustom.testname}")
	private String coustomName;

	@Value("${coustomfile.username}")
	private String username;
	
	@Autowired
	private Environment env;
	
    // lb.env.dynamic.attr 为pom.xml配置的信息
    // 这里会根据application.properties配置的spring.profiles.active值动态获取pom.xml配置的信息
    // 例如spring.profiles.active=dev,那么dynamicAttr=2020-12-12-dev
    // 如果spring.profiles.active=pro,那么dynamicAttr=2020-12-15-pro
	@Value("${lb.env.dynamic.attr}")
	private String dynamicAttr;
	
	
	public void output() {
		LOGGER.info("使用 @Value 读取到的自定义配置: {}", coustomName);
		LOGGER.info("使用 @Autowired Environment 读取到的自定义配置: {}", env.getProperty("applicationfile.coustom.testname"));
		LOGGER.info("加载自定义配置文件 - username: {},",username);
        // 打印动态配置内容
		LOGGER.info("动态获取pom.xml配置 - dynamicAttr value: {}",dynamicAttr);
		
	}
}

1. 在项目上,鼠标右键选择 --->Run As ---> Maven build...

2. 弹出对话框后,在Goals输入框 输入clean install -P pro ,点击run

3. 等待maven打包完毕后,项目 /target 目录显示如下:

4. 我们把第一个文件lb-springboot-quickstart.jar 复制一份,放在桌面,解压后查看编译后的内容。

打开BOOT-ROOT ---> classes 查看application.properties内容。因为打包时指定的-P pro所以编译后的文件获取的是pro环境的配置

我们再查看下 myconfig.properties的内容,看有没有动态获取到 pom.xml配置的变量。答案很明显,说明properties动态获取pom.xml的变量没有问题。

接下来我们来测试一下,项目中[@Value](https://my.oschina.net/u/3193899)读取的pom.xml变量是否有问题。

使用命令 java -jar lb-springboot-quickstart.jar 启动项目,查看控制台如下:

结果如下:

  1. spring.profiles.active=pro
  2. 并且应用端口是获取的application-pro.properties的配置
  3. 同时也在appconfig.java获取到了POM.xml中的变量 lb.env.dynamic.attr的值。

有兴趣的同学可以使用   clean install -P dev  打包,打包后使用命令  java -jar lb-springboot-quickstart.jar 启动项目进一步校验结果。 案例代码下载:https://github.com/yunnasheng/springboot-quickstart-001.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值