我面对的是Spring配置的奇怪问题,因为application.properties
以特定方式命名配置时,环境变量不会覆盖其中定义的配置。如外部化配置 OS中所述,环境变量优先于,application.properties
但是在将配置定义为时不会发生这种情况,myExternal_url
但是在将配置定义为时才起作用my_external_url
(在下面的示例代码中,我们需要将配置更改为my_external_url
in ApplicationProperties.java
和application.properties
)
示例代码-
@SpringBootApplication
public class ConfigApplication implements ApplicationRunner {
@Autowired private ApplicationProperties applicationProperties;
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
@Override
public void run(ApplicationArguments arg0) {
System.out.println("External URL = " + applicationProperties.getMyExternalUrl());
}
}
应用Bean配置-
@Configuration
public class AppConfig {
@Bean
@ConfigurationProperties(prefix = "")
public ApplicationProperties applicationProperties() {
return new ApplicationProperties();
}
}
ApplicationProperties
类-
public class ApplicationProperties {
@Value("${myExternal_url}")
private String myExternalUrl;
public String getMyExternalUrl() {
return this.myExternalUrl;
}
public void setMyExternalUrl(String myExternalUrl) {
this.myExternalUrl = myExternalUrl;
}
}
application.properties
:
myExternal_url=external_url_env_application_properties
这可能是什么原因?
编辑-添加gradle Gradle配置
plugins {
id 'org.springframework.boot' version '2.4.0-M1'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
compileOnly 'org.projectlombok:lombok:1.18.6'
annotationProcessor 'org.projectlombok:lombok:1.18.6'
}
test {
useJUnitPlatform()
}
编辑2
跟踪日志显示myExternal_url已从Environment变量正确解析。然后,Spring尝试applicationProperties
通过调用解析自动装配的依赖项' ' AutowiredAnnotationBeanPostProcessor
,然后使用application.properties值覆盖该值(屏幕截图)。
o.s.c.e.PropertySourcesPropertyResolver : Found key 'myExternal_url' in PropertySource 'systemEnvironment' with value of type String
o.s.c.e.PropertySourcesPropertyResolver : Found key 'myExternal_url' in PropertySource 'environmentProperties' with value of type String
TL; DR 从注入的系统变量中得出了@Value
正确的myExternal_Url
信息,但其值稍后由设置@ConfigurationProperties
。
跟踪日志是正确的,因为来自Spring的顺序将放在propertySource列表中的systemEnvironment
前面classpath:/application.properties
。
您遇到的问题是由于同时使用@Value
和@ConfigurationProperties
插入/绑定属性而引起的。说这些是您提供的值:
system:
myExternal_Url: foo
my_external_url: bar
applications.properties:
myExternal_url: aaa
在您的ApplicationProperties中:
@Value("${myExternal_url}")
private String myExternalUrl; // injected with foo
myExternalUrl
正确注入了foo
您在环境变量中定义的值()。但是,使用setter方法@ConfigurationProperties
绑定值之后。由于它使用宽松的绑定,因此会检查的不同变体myExternalUrl
,它首先查找系统变量中的内容,然后发现myExternal_url
(骆驼和Underscore)都不是宽松的绑定形式之一,然后my_external_url
(仅下划线)出现。因此my_external_url
,将的值提供给setter:
public void setMyExternalUrl(String myExternalUrl) { // bar
this.myExternalUrl = myExternalUrl; // myExternalUrl is reassigned from foo to bar
}
因此应该清楚,@Value
由于@ConfigurationProperties
绑定值之后,您将始终被覆盖。只需拥有:
public class ApplicationProperties {
private String myExternalUrl;
...
然后在系统中定义一种绑定形式- MY_EXTERNAL_URL
,my-external-url
或my_external_url
(也许还有更多)。然后,在application.yml中使用一致的大小写,以防不希望使用系统变量。
my-external-url=aaa
边注。建议您将该表格MY_EXTERNAL_URL
用作系统环境变量。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句