跳到最底层,了解这个问题的动机和解决方案!
在从Spring Boot 1.4
升级到1.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的课程根本不会被验证。
因此,我努力地将@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.properties
:demo.prop=${profile.prop}
application-demo.properties
:profile.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提供完整的应用程序(包括一个测试用例,显示在profile.prop
中定义config/application.properties
也失败了@validated
但在没有成功的情况下成功。
我想这是Spring Boot中的一个错误,但是我可能不会理解某些内容,所以首先是SoF(正如Spring Boot在github上发布的经理所示)。
这个github问题似乎有关:https://github.com/spring-projects/spring-boot/issues/8173
答案 0 :(得分:1)
当我找到我的问题的解决方案时(前段时间已经提到,但在问题本身中作为解释添加),我认为在这里复制我的发现可能更有帮助。
我的示例代码的问题是@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。基本上,BeanPostProcessor
和spring-cloud
之间的spring-boot
之间存在冲突(github上的票证中的详细信息),Dalston.RELEASE
spring-cloud
解决了此问题。只是更新我们项目中的依赖项也解决了生产中的问题。很多挖掘和测试只是在我们的代码库中更改了7个字符。