一.引言:一个配置失效引发的思考
java
package com.example.demo.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Slf4j
@Component
@PropertySource(value = {"classpath:app.properties"}, ignoreResourceNotFound = true)
public class ServiceDomainConfig {
@Value("${service.domain.url}")
private String url;
@Value("${service.domain.accessKey}")
private String accessKey;
public String getUrl() {
return url;
}
public String getAccessKey() {
return accessKey;
}
@PostConstruct
public void init() {
log.info("ServiceDomainConfig loading...");
log.info(" url: {}", url == null ? "NULL" : "OK");
log.info(" accessKey: {}", accessKey == null ? "NULL" : "OK ***");
if (isEmpty(url)) {
throw new IllegalArgumentException(
"ServiceDomainConfig validation failed: service.domain.url is empty. " +
"Please check app.properties configuration."
);
}
if (isEmpty(accessKey)) {
throw new IllegalArgumentException(
"ServiceDomainConfig validation failed: service.domain.accessKey is empty. " +
"Please check app.properties configuration."
);
}
log.info("ServiceDomainConfig validation passed");
}
private boolean isEmpty(String value) {
return value == null || value.trim().isEmpty();
}
}
如果在ssm项目中不配置PropertyPlaceholderConfigurer,上面的类启动便会报错,即使@PropertySource指定了配置文件也没用,因为@Value注解里面的值无法被解析。
二.SSM项目配置
正确的配置如下:
xml文件中需要配置PropertyPlaceholderConfigurer
java
<!-- 必须手动配置 -->
<bean class="PropertyPlaceholderConfigurer">
<property name="location" value="classpath:app.properties"/>
</bean>
或者
java
<!-- applicationContext.xml -->
<context:property-placeholder
location="classpath:app.properties"
ignore-resource-not-found="true"
ignore-unresolvable="false"/>
该配置会在没找到属性资源时自动忽略对应属性。而且还可以配置从环境变量里面找值,这里就没有配置。
对应配置类如下:
java
package com.test.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.annotation.PostConstruct;
/**
* OSFP 通知平台配置
*
* @Date 2022/05/24
* @Author linxl
*/
@Slf4j
@Configuration
@PropertySource(value = {"classpath:sys.properties"}, ignoreResourceNotFound = true)
public class OsfpApiConfig {
@Value("${notice.url}")
private String url;
@Value("${notice.appid}")
private String clientId;
@Value("${notice.appSecret}")
private String clientSecret;
@Value("${notice.grantType}")
private String grantType;
@Value("${notice.lamsUrl}")
private String issUrl;
@PostConstruct
public void init() {
log.info("OsfpApiConfig 初始化完成 - URL: {}, ClientId: {}", url, clientId);
}
public String getUrl() {
return url;
}
public String getClientId() {
return clientId;
}
public String getClientSecret() {
return clientSecret;
}
public String getGrantType() {
return grantType;
}
public String getIssUrl() {
return issUrl;
}
}
通过这种方式便能够解析@value属性里面的值,其实@PropertySource注解也可以省略。因为通过xml的方式已经加载了对应的配置文件,并把里面的属性注入到了spring的environment里面,@Value可以正常拿到值。
三.springboot项目的配置
然而boot项目简化了许多,我们不需要配置PropertyPlaceholderConfigurer或其子类,通过下面的方式就能绑定配置文件并拿到值,而且不用加@Value注解,不用指定层级,自动可以解析相关属性。
配置类如下:
java
package com.test.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 通知平台配置
*
* @Date 2022/05/24
* @Author linxl
*/
@Configuration
@ConfigurationProperties(prefix = "osfp")
public class OsfpApiConfig {
String clientId;
String clientSecret;
String grantType;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getGrantType() {
return grantType;
}
public void setGrantType(String grantType) {
this.grantType = grantType;
}
}
application.xml配置文件如下:
java
osfp:
url: http://open-trest.sit.sf-express.com:8080
clientId: adfcd86498d04f0ba14d5775a20c0b18
clientSecret: bde733ffd494446794cab3e8bcc1701f
grantType: client_credentials