2017-04-18 94 views
3

跳轉到底部尋找動機和解決方案!Spring Boot 1.5已驗證配置屬性

在升級,從春天啓動的過程1.41.5我讀(來源:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.5-Release-Notes#upgrading-from-spring-boot-14

如果您有使用JSR-303約束註釋@ConfigurationProperties類,你現在應該還使用@註釋它們驗證。現有的驗證將繼續有效,但會記錄警告。將來,沒有@Validated的類將不會被驗證。

因此,我認真地將@Validated添加到我的所有配置屬性中。現在我有一個特定的用例斷了,又名該屬性不再被加載(我首先總結,然後添加代碼)。

如果我使用application.properties文件中定義的模板屬性,然後嘗試覆蓋特定配置文件的值,那麼應用程序不會啓動。

下面是一些示例代碼重現(相關文件):

build.gradle

buildscript { 
    ext { 
     springBootVersion = '1.5.1.RELEASE' 
    } 
    repositories { 
     mavenCentral() 
    } 
    dependencies { 
     classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 
    } 
} 

apply plugin: 'java' 
apply plugin: 'eclipse' 
apply plugin: 'org.springframework.boot' 

version = '0.0.1-SNAPSHOT' 
sourceCompatibility = 1.8 

repositories { 
    mavenCentral() 
} 


dependencies { 
    compile('org.springframework.boot:spring-boot-starter-web') 
    testCompile('org.springframework.boot:spring-boot-starter-test') 
} 

application.propertiesdemo.prop=${profile.prop}

application-demo.propertiesprofile.prop=demo

DemoApplication.java

package package; 

import javax.validation.constraints.NotNull; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.boot.context.properties.ConfigurationProperties; 
import org.springframework.stereotype.Component; 
import org.springframework.validation.annotation.Validated; 
import org.springframework.web.bind.annotation.GetMapping; 

@SpringBootApplication 
public class DemoApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(DemoApplication.class, args); 
    } 

    @org.springframework.web.bind.annotation.RestController 
    public static class RestController { 

     @Autowired 
     private DemoProperties properties; 

     @GetMapping 
     public String get() { 
      return properties.prop == null ? "null" : properties.prop; 
     } 
    } 

    @Component 
    @ConfigurationProperties(prefix = "demo") 
// @Validated 
    public static class DemoProperties { 

     @NotNull 
     private String prop; 

     public void setProp(String prop) { 
      this.prop = prop; 
     } 

     public String getProp() { 
      return prop; 
     } 
    } 
} 

既然這樣,我的應用程序產生預期的結果時-Dspring.profiles.active=demo

curl "http://localhost:8080" 
demo 
然而

運行,取消註釋//@validated和運行應用程序之前產生

curl "http://localhost:8080" 
null 

可在https://github.com/ThanksForAllTheFish/boot-props全部應用(包括一個測試案例,顯示在config/application.properties中定義profile.prop失敗以及@validated但沒有成功)。我猜這是Spring Boot中的一個bug,但它可能不是我理解的東西,所以SoF首先(如在github上的Spring Boot問題管理器中暗示的那樣)。

這GitHub的問題似乎涉及:https://github.com/spring-projects/spring-boot/issues/8173

+0

我實際上使用例更加複雜,它必須是。只需將demo.prop = prop的application.properties作爲單行內容就足以看到相同的問題。我更新了github回購 – ThanksForAllTheFish

+0

你沒有包含驗證器,因此沒有任何驗證。這樣的重寫屬性也不起作用。這不是一個多通道的過程,所有的東西都被讀取然後處理......所以只要將它指定爲系統屬性,環境屬性或啓動參數就會覆蓋 –

+0

@ M.Deinum,如我所寫,不是真的,如果我刪除'@ Validated'應用程序按預期運行。我很驚訝以及我不需要一個驗證器,但是如果我清空我的application.properties文件,我得到一個BindException – ThanksForAllTheFish

回答

0

正如我找到了解決我的問題(前一段時間了,但添加在問題本身說明),我想它可能更有助於複製我的發現這裏。

與我的示例代碼的問題是,@Validated包裝與代理的真正類,以便驗證擔憂可以注入,因此返回properties.prop == null ? "null" : properties.prop;實際上是試圖訪問代理服務器的prop領域。更改爲getProp()是修復程序。很明顯,一旦發現。

關於生產代碼:問題與https://github.com/spring-projects/spring-boot/issues/8173有關,或者更準確地說與https://github.com/spring-cloud/spring-cloud-commons/issues/177有關,因爲我們使用了spring-cloud。基本上,spring-cloudspring-boot(在github上的票證中的細節)在BeanPostProcessor之間存在衝突,在spring-cloudDalston.RELEASE中解決。只是更新項目中的依賴關係,也解決了生產中的問題。很多挖掘和測試只是改變我們的代碼庫中的7個字符。