Spring 引导 - 添加外部 属性 文件
Spring Boot - add external property files
我在 SpringBoot 中有简单的 MVC 应用程序,使用 java-config 创建(我没有 web.xml)。
该应用程序具有基于 JPA 的数据库连接。到现在为止,一切都很好,但现在我必须将 db.properties 从 WAR 内部移动到 OS 变量 ("CONFIG_LOCATION") 指定的位置。
在spring doc里面写的不多。只是说它是可能的,但我应该如何在我的 Spring 应用程序中设置它?
我想应该在初始化程序之前完成。
然后我只看到两个选项:
- Spring应用程序 - 有一个地方我应该从 OS 变量插入文件位置但我找不到它,
- 一些注释,将理解 OS 变量,并在创建 EntityManager 之前将文件从它添加到 spring 上下文。
我愿意接受建议,我应该怎么做。
如果使用spring-boot的配置参数,只需在执行jar或war时指定配置位置,参数--spring.config.location.
示例:
$ java -jar myproject.jar --spring.config.location=/opt/webapps/db.properties
好的,我找到方法了。
我创建了 class 什么 return PropertySourcesPlaceholderConfigurer。
在那个 PSPC 中,我得到 OS 变量,并扫描该位置的所有文件。
扫描后,我将所有具有属性扩展名的文件添加到 PSCS 作为位置。
方法是@Bean,class是@Configuration。之后一切正常:)
imports...
@Configuration
public class AppServiceLoader {
@Bean(name = "propLoader")
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
String mainConfigPath = StringUtils.isNotEmpty(System.getenv("CONFIG_LOCATION"))
? System.getenv("CONFIG_LOCATION") : System.getProperties().getProperty("CONFIG_LOCATION");
File configFolder = new File(mainConfigPath);
if(configFolder.isDirectory()) {
FilenameFilter ff = new FilenameFilter() {
@Override
public boolean accept(File file, String string) {
return string.endsWith(".properties");
}
};
File[] listFiles = configFolder.listFiles(ff);
Resource[] resources = new Resource[listFiles.length];
for (int i = 0; i < listFiles.length; i++) {
if(listFiles[i].isFile()) {
resources[i] = new FileSystemResource(listFiles[i]);
}
}
pspc.setLocations(resources);
}
pspc.setIgnoreUnresolvablePlaceholders(true);
return pspc;
}
}
您也可以使用注解@PropertySource
。它比代码解决方案更清晰和干净。
例如:
@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
...
如果您只想Spring引用项目根目录下的外部属性文件。
这是一个更简单的解决方案:
@Configuration
@PropertySource("file:${user.dir}/your_external_file.properties")
public class TestConfig {
@Autowired
Environment env;
}
如有必要,您可以将 ${user.dir} 更改为 ${user.home}。
正如另一个答案中提到的 @PropertySource 注释是可行的方法(我将添加一些细节)。在 Java 8 中,您可以多次将其应用于您的配置 class,顺序很重要!例如你可以这样配置:
@SpringBootApplication
@PropertySource("classpath:/db.properties")
@PropertySource(ignoreResourceNotFound = true, value = "file:${MY_APP_HOME}/db.properties")
@PropertySource(ignoreResourceNotFound = true, value = "file:${user.home}/.myapp/db.properties")
@ComponentScan("com.myorg")
public class Application {
// ....
}
这里我假设你应该有 MY_APP_HOME
环境变量,而且你可能想在用户主目录中放置一些设置。但是这两个配置都是可选的,因为 ignoreResourceNotFound
设置为 true。
另请注意订单。 src/main/resources/db.properties
你可能对开发环境有一些合理的设置。并将特定设置放在运行生产服务的主机 OS 中。
查看 javadoc 中的 Resolving ${...} placeholders within @PropertySource resource locations
部分了解详细信息。
我在 SpringBoot 中有简单的 MVC 应用程序,使用 java-config 创建(我没有 web.xml)。
该应用程序具有基于 JPA 的数据库连接。到现在为止,一切都很好,但现在我必须将 db.properties 从 WAR 内部移动到 OS 变量 ("CONFIG_LOCATION") 指定的位置。
在spring doc里面写的不多。只是说它是可能的,但我应该如何在我的 Spring 应用程序中设置它?
我想应该在初始化程序之前完成。
然后我只看到两个选项:
- Spring应用程序 - 有一个地方我应该从 OS 变量插入文件位置但我找不到它,
- 一些注释,将理解 OS 变量,并在创建 EntityManager 之前将文件从它添加到 spring 上下文。
我愿意接受建议,我应该怎么做。
如果使用spring-boot的配置参数,只需在执行jar或war时指定配置位置,参数--spring.config.location.
示例:
$ java -jar myproject.jar --spring.config.location=/opt/webapps/db.properties
好的,我找到方法了。
我创建了 class 什么 return PropertySourcesPlaceholderConfigurer。
在那个 PSPC 中,我得到 OS 变量,并扫描该位置的所有文件。
扫描后,我将所有具有属性扩展名的文件添加到 PSCS 作为位置。
方法是@Bean,class是@Configuration。之后一切正常:)
imports...
@Configuration
public class AppServiceLoader {
@Bean(name = "propLoader")
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
String mainConfigPath = StringUtils.isNotEmpty(System.getenv("CONFIG_LOCATION"))
? System.getenv("CONFIG_LOCATION") : System.getProperties().getProperty("CONFIG_LOCATION");
File configFolder = new File(mainConfigPath);
if(configFolder.isDirectory()) {
FilenameFilter ff = new FilenameFilter() {
@Override
public boolean accept(File file, String string) {
return string.endsWith(".properties");
}
};
File[] listFiles = configFolder.listFiles(ff);
Resource[] resources = new Resource[listFiles.length];
for (int i = 0; i < listFiles.length; i++) {
if(listFiles[i].isFile()) {
resources[i] = new FileSystemResource(listFiles[i]);
}
}
pspc.setLocations(resources);
}
pspc.setIgnoreUnresolvablePlaceholders(true);
return pspc;
}
}
您也可以使用注解@PropertySource
。它比代码解决方案更清晰和干净。
例如:
@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
...
如果您只想Spring引用项目根目录下的外部属性文件。
这是一个更简单的解决方案:
@Configuration
@PropertySource("file:${user.dir}/your_external_file.properties")
public class TestConfig {
@Autowired
Environment env;
}
如有必要,您可以将 ${user.dir} 更改为 ${user.home}。
正如另一个答案中提到的 @PropertySource 注释是可行的方法(我将添加一些细节)。在 Java 8 中,您可以多次将其应用于您的配置 class,顺序很重要!例如你可以这样配置:
@SpringBootApplication
@PropertySource("classpath:/db.properties")
@PropertySource(ignoreResourceNotFound = true, value = "file:${MY_APP_HOME}/db.properties")
@PropertySource(ignoreResourceNotFound = true, value = "file:${user.home}/.myapp/db.properties")
@ComponentScan("com.myorg")
public class Application {
// ....
}
这里我假设你应该有 MY_APP_HOME
环境变量,而且你可能想在用户主目录中放置一些设置。但是这两个配置都是可选的,因为 ignoreResourceNotFound
设置为 true。
另请注意订单。 src/main/resources/db.properties
你可能对开发环境有一些合理的设置。并将特定设置放在运行生产服务的主机 OS 中。
查看 javadoc 中的 Resolving ${...} placeholders within @PropertySource resource locations
部分了解详细信息。