java 如何使用 Spring Boot 加载外部配置?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43755380/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to load an external configuration with Spring Boot?
提问by Morph
I'm currently learning how to work with Spring Boot. Until now I never used Frameworks like Spring and used files directly (FileInputStream, etc.)
我目前正在学习如何使用 Spring Boot。到目前为止,我从未使用过 Spring 之类的框架,而是直接使用文件(FileInputStream 等)
So here is the case: I have some dynamic configuration values like OAuth tokens. I want to use them inside of my application but I have no clue how to realize this with Spring.
所以情况是这样的:我有一些动态配置值,比如 OAuth 令牌。我想在我的应用程序中使用它们,但我不知道如何用 Spring 实现这一点。
Here is some code to make clear what I'm searching for:
下面是一些代码来明确我在搜索什么:
@Config("app.yaml")
public class Test {
@Value("app.token")
private String token;
private IClient client;
public Test(String token) {
this.client = ClientFactory.build(token).login();
}
}
Sure, this example is very plain. Here I want to get the value "token" dynamically from a YAML configuration file. This file must be accessible for the user and not included in the JAR file.
当然,这个例子很简单。在这里,我想从 YAML 配置文件中动态获取值“令牌”。该文件必须可供用户访问,并且不包含在 JAR 文件中。
I also found that doc: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.htmlbut I have now idea how to apply this to my project.
我还发现了该文档:https: //docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html但我现在知道如何将其应用于我的项目。
How can I achive this? Thank you in advance :)
我怎样才能做到这一点?先感谢您 :)
Edit:
编辑:
Here are some parts of my code:
这是我的代码的一些部分:
WatchdogBootstrap.java
看门狗引导程序
package de.onkelmorph.watchdog;
import org.springframework.boot.Banner.Mode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource("classpath:Beans.xml")
public class WatchdogBootstrap {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(WatchdogBeans.class);
app.setBannerMode(Mode.OFF);
app.setWebEnvironment(false);
app.run(args);
}
}
Beans.xml(Located in default package)
Beans.xml(位于默认包中)
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config></context:annotation-config>
</beans>
Watchdog.java
看门狗
package de.onkelmorph.watchdog;
// Imports ...
@Component
@PropertySource("file:/watchdog.yml")
public class Watchdog {
// ...
// Configuration
@Value("${watchdog.token}")
private String token;
public Watchdog() {
System.out.println(this.token);
System.exit(0);
}
// ...
}
watchdog.yml(Located in src/main/resources)
watchdog.yml(位于 src/main/resources)
watchdog:
token: fghaepoghaporghaerg
采纳答案by Tom
First of all your Test
class should be annotated with @Component
in order for it to be registered as a bean by spring (also make sure all your classes are under your main package - the main package is where a class that is annotated with @SpringBootApplication
reside).
首先,您的Test
类应该被注释,@Component
以便它在 spring 之前注册为 bean(还要确保您的所有类都在您的主包下 - 主包是带有注释的类@SpringBootApplication
所在的位置)。
Now you should either move all your properties to application.yml
(src/main/resources/application.yml
), that is picked automatically by spring boot (note that it should be .yml
instead of .yaml
or register a custom PropertySourcesPlaceholderConfigurer
.
现在,您应该将所有属性移动到application.yml
( src/main/resources/application.yml
),即由 spring boot 自动选择(请注意,它应该.yml
代替.yaml
或注册自定义PropertySourcesPlaceholderConfigurer
.
Example for PropertySourcesPlaceholderConfigurer
:
示例PropertySourcesPlaceholderConfigurer
:
@Bean
public static PropertySourcesPlaceholderConfigurer PropertySourcesPlaceholderConfigurer() throws IOException {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
MutablePropertySources propertySources = new MutablePropertySources();
Resource resource = new DefaultResourceLoader().getResource("classpath:application.yml");
YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader();
PropertySource<?> yamlProperties = sourceLoader.load("yamlProperties", resource, null);
propertySources.addFirst(yamlProperties);
configurer.setPropertySources(propertySources);
return configurer;
}
Now your properties should be loaded to spring's environment and they will be available for injection with @Value
to your beans.
现在你的属性应该被加载到 spring 的环境中,它们将可用于注入@Value
到你的 bean 中。
回答by kkflf
You basically got three easy options.
你基本上有三个简单的选择。
- Use
application.properties
which is Springs internal configuration file. - Load your own configuration file using
--spring.config.name
as VM parameter. - You can use
@PropertySource
to load either an internal or external configuration.@PropertySource
only works with .properties config files. There is currently an open Jira ticket to implement yaml support. You can follow the progress here: https://jira.spring.io/browse/SPR-13912
- 使用
application.properties
哪个是 Springs 的内部配置文件。 - 使用
--spring.config.name
作为 VM 参数加载您自己的配置文件。 - 您可以使用
@PropertySource
加载内部或外部配置。@PropertySource
仅适用于 .properties 配置文件。目前有一个开放的 Jira 票来实现 yaml 支持。您可以在此处跟踪进度:https: //jira.spring.io/browse/SPR-13912
Notice, if you are using multiple yaml and/or properties files which contain common keys, the it will always use the definition of the key which was loaded last. This is why the below example uses two different keys. If it used the same key, then it would print out PROPERTIES FILE
twice.
请注意,如果您使用包含公共密钥的多个 yaml 和/或属性文件,它将始终使用最后加载的密钥的定义。这就是为什么下面的例子使用两个不同的键。如果它使用相同的密钥,那么它会打印PROPERTIES FILE
两次。
Short simple code snippet:
简短的代码片段:
@Component
@PropertySource("file:/path/to/config/app.properties")
class Address{
@Value("${addr.street}")
private String street;
@Value("${addr.city}")
private String city;
}
app.properties
app.properties
addr.street=Abbey Road
addr.city=London
Extensive Example
广泛的例子
DemoApplication.java
演示应用程序.java
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
//Call class with properties
context.getBean(WatchdogProperties.class).test();
//Call class with yaml
context.getBean(WatchdogYaml.class).test();
}
//Define configuration file for yaml
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ClassPathResource("watchdog.yml"));
propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject());
return propertySourcesPlaceholderConfigurer;
}
}
WatchdogProperties.java
看门狗属性.java
@Component
//PropertySource only works for .properties files
@PropertySource("classpath:watchdog.properties")
public class WatchdogProperties{
//Notice the key name is not the same as the yaml key
@Value("${watchdog.prop.token}")
private String token;
public void test(){
System.out.println(token);
}
}
WatchdogYaml.java
WatchdogYaml.java
@Component
class WatchdogYaml{
//Notice the key name is not the same as the properties key
@Value("${watchdog.token}")
private String token;
public void test(){
System.out.println(token);
}
}
Properties and Yaml filesBoth of these files are located in src/main/resources
属性和 Yaml 文件这两个文件都位于src/main/resources
watchdog.yml:
看门狗.yml:
watchdog:
token: YAML FILE
watchdog.properties:
watchdog.properties:
watchdog.prop.token=PROPERTIES FILE
Output
输出
PROPERTIES FILE
YAML FILE