Spring Boot配置文件如何覆盖Apollo
问题背景
在使用Spring Boot开发应用时,我们经常使用配置文件来配置应用的各项属性。而在实际的项目中,可能会使用Apollo作为配置中心来管理配置文件,以便动态地调整配置项。然而,当我们使用Apollo时,如何保证配置文件的优先级,使得我们可以方便地覆盖Apollo中的配置项,成为了一个需要解决的问题。
解决方案
为了解决这个问题,我们可以通过对Spring Boot的配置加载过程进行调整来实现。Spring Boot会按照固定的顺序加载配置文件,我们可以通过在应用启动时指定配置文件的加载顺序,来实现Apollo配置文件的覆盖。
配置文件加载顺序
Spring Boot默认的配置文件加载顺序为:application.properties
-> application.yml
-> bootstrap.properties
-> bootstrap.yml
。其中,bootstrap
开头的配置文件优先级更高,会覆盖application
开头的配置文件。
方案步骤
-
在项目的
resources
目录下创建bootstrap.properties
或bootstrap.yml
文件,并将Apollo的配置项写入该文件中。这样做的目的是让Apollo的配置文件先加载,以便覆盖后续加载的配置文件。 -
在启动应用的时候,通过命令行参数或启动脚本指定
spring.config.name
和spring.config.location
的值,以指定应用的配置文件名和加载路径。-
通过命令行参数指定:
java -jar myproject.jar --spring.config.name=myproject --spring.config.location=classpath:/config/
-
通过启动脚本指定:
java -jar myproject.jar -Dspring.config.name=myproject -Dspring.config.location=file:/opt/myproject/config/
这样做可以确保在启动应用时,优先加载指定位置的配置文件,而不是默认的配置文件。
-
-
确保应用的配置文件中有
spring.profiles.active
属性,并设置为default
。这样可以确保Apollo的配置项在其他Profile中被覆盖。spring: profiles: active: default
-
在应用的配置文件中,通过
${}
占位符来使用Apollo中的配置项。在Apollo中创建相应的命名空间和配置项,并为其设定合适的值。# application.yml server: port: ${server.port}
这样,应用在启动时会先加载Apollo的配置文件,然后再加载应用的配置文件,其中的占位符会被Apollo的配置值替换掉。
-
启动应用,Apollo的配置项就会覆盖应用中相同的配置项。
类图
下面是一个简化的类图,展示了上述解决方案的类和关系。
classDiagram
class ApolloConfig {
+getProperty(key: String): String
}
class ConfigFile {
+load(file: String): Properties
+getProperty(key: String): String
}
class Application {
+main(args: String[]): void
-resolveConfigLocation(): String
}
class Bootstrap {
+main(args: String[]): void
-resolveConfigLocation(): String
}
Application --> ConfigFile
Bootstrap --> ConfigFile
Application --> ApolloConfig
Bootstrap --> ApolloConfig
示例代码
下面是一个示例代码,演示了如何使用上述解决方案来实现Apollo配置文件的覆盖。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
@Configuration
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// 指定应用的配置文件名和加载路径
System.setProperty("spring.config.name", "myproject");
System.setProperty("spring.config.location", "classpath:/config/");
// 设置默认Profile
System.setProperty("spring.profiles.active", "default");
SpringApplication.run(Application.class, args);
}
}
# application.yml
server:
port: ${server.port}
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigService;
@Configuration
public class ApolloConfig {
private static final String APOLLO_NAMESPACE = "myproject";
public String getProperty