2017-05-03 74 views
1

我目前在學習如何使用Spring Boot。到目前爲止,我從來沒有像Spring一樣使用框架,並直接使用文件(FileInputStream等)。如何使用Spring Boot加載外部配置?

因此,情況如下:我有一些動態配置值,如OAuth令牌。我想在我的應用程序中使用它們,但我不知道如何通過Spring實現這一點。

下面是一些代碼來明確一下我在尋找:

@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(); 
    } 
} 

當然,這個例子是非常簡單的。在這裏我想從YAML配置文件中動態獲取值「token」。該文件必須可供用戶訪問,並且不包含在JAR文件中。

我還發現該文檔:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html但我現在已經知道如何將其應用於我的項目。

我該如何實現這一目標?預先感謝您:)

編輯:

這裏是我的代碼的某些部分:

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(位於默認包)

<?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(放在src /主/資源)

watchdog: 
    token: fghaepoghaporghaerg 
+0

我並不想成爲粗魯,但你閱讀文件?有什麼需要幫助的嗎?通常情況下,如果你想加載一個外部配置文件,你可以使用像'java -jar myproject.jar --spring.config.name = myproject'這樣的東西,我很樂意提供幫助,但我需要知道你需要幫助的部分用。在你所說的文獻中,一切都很好解釋清楚。 – kkflf

+0

嗨kkflf,謝謝你的回覆!當然,我閱讀文檔,但我認爲我沒有得到他們......有沒有一種方法來加載配置沒有額外的虛擬機參數?謝謝! – Morph

+0

當然,這是可能的。你應該看看'@ PropertySource'。此註釋將允許您加載內部和外部配置文件。如果你的項目跨越多個開發環境,你應該看看分析或使用虛擬機參數,但不要關注這個,直到你得到配置文件的工作。請記住如何使您的應用程序配置適合多種工作環境。 – kkflf

回答

3

所有Test類首先應@Component爲了進行註釋因爲它將在春季註冊爲一個bean(還要確保你的所有課程都在你的主包裝下 - 主包裝是一個註釋爲的課程駐留)。

現在,您應該將所有的屬性application.ymlsrc/main/resources/application.yml),由春季開機自動拾取(請注意,它應該是.yml代替.yaml或註冊自定義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; 
} 

你的屬性應該被加載到春天的環境,他們將可用於注射@Value你的豆。

+0

嗨@Tom並感謝您的支持。我也試過你的解決方案,但它不適合我......我在上面的問題中追加了一些代碼片斷,也許在某處存在錯誤? – Morph

+0

嗨,上面的代碼有一些問題。 1)不要混合使用XML和Java配置,這會產生很多問題,因爲它是默認值,所以不需要定義'annotation-config'。所以你可以刪除'@ImportResource(「classpath:Beans.xml」)'2)'@ PropertySource'不適用於yaml。 3)我給的'@ Bean'例子應該在'WatchdogBootstrap.java'或者'@ Configuration'註釋類中。 4)對於文件系統資源,使用'new FileSystemResource(...)'而不是'new DefaultResourceLoader()。getResource(...)' – Tom

+0

如果你的文件在'src/main/resources'中並且你定義了這個bean,它將使用'新的DefaultResourceLoader()。getResource(「classpath:watchdog.yml」);' – Tom

1

你基本上有三個簡單的選擇。

  1. 使用application.properties這是Springs內部配置文件。
  2. 使用--spring.config.name作爲VM參數加載您自己的配置文件。
  3. 您可以使用@PropertySource加載內部或外部配置。 @PropertySource僅適用於.properties配置文件。目前有一個開放的Jira票據來實施yaml支持。您可以按照進度在這裏:https://jira.spring.io/browse/SPR-13912

注意,如果您正在使用多個YAML和/或屬性包含公共密鑰文件時,它總是使用的加載最後關鍵的定義。這就是爲什麼下面的例子使用兩個不同的鍵。如果它使用相同的密鑰,那麼它會打印出PROPERTIES FILE兩次。

短簡單的代碼片斷:

@Component 
@PropertySource("file:/path/to/config/app.properties") 
class Address{ 

    @Value("${addr.street}") 
    private String street; 

    @Value("${addr.city}") 
    private String city; 
} 

app.properties

addr.street=Abbey Road 
addr.city=London 

廣泛實施例

DemoApplication.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

@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

@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); 
    } 
} 

屬性和YAML文件 這兩個文件都位於src/main/resources

watchdog.yml:

watchdog: 
    token: YAML FILE 

watchdog.properties:

watchdog.prop.token=PROPERTIES FILE 

輸出

PROPERTIES FILE 
YAML FILE 
+0

Fyi:我沒有測試上面的代碼,因爲我無法做到這一點。如果有人發現錯誤,請告訴我。 – kkflf

+0

您好@kkflf,感謝您的支持!不幸的是,它迄今爲止並不奏效......我在上面的問題中附加了一些代碼片斷。我使用Maven構建項目,而watchdog.yml文件位於項目根目錄。 – Morph

+0

'@PropertySource(「file:/watchdog.yml」)'看起來是錯的。這不是項目的根源。請將其更改爲'@PropertySource(「classpath:watchdog.yml」)' – kkflf

相關問題