通过配置文件绑定属性值(@ConfigurationProperties 和 @Value)
通过配置文件绑定属性值(@ConfigurationProperties 和 @Value)
最近在做微信支付,做的过程需要将微信appId、secret、商户号等等很多参数通过实体类注入到配置类中,有两种方式,这里都写一下。一共有两种,一种是写properties配置文件,一种是通过yaml文件绑定,最后对比一下@ConfigurationProperties和@Value的区别。
1. properties配置文件绑定
新建一个微信支付参数实体类 WCPConfigParams
@Data
public class WCPConfigParams {
// 公众号id
private String appId;
// app**
private String appSecret;
// 商户号
private String muchId;
// api**
private String apiKey;
// 公众号注册域名
private String registerDomain;
// jsapi支付目录
private String jsapiPaymentAuthDir;
// js安全域名
private String jsDomain;
// 网页授权域名
private String webAuthDomain;
// 证书目录
private String apiclientCert;
// 押金支付回调地址
private String notifyUrl;
// 取包支付回调地址
private String takeNotifyUrl;
// 退款回调地址
private String notifyUrlRefund;
}
在resources下建立wcp-config.properties
配置文件
wcp.APP_ID=
wcp.APPSECRET=
wcp.MCH_ID=
wcp.API_KEY=
wcp.REGISTER_DOMAIN=
wcp.JSAPI_PAYMENT_AUTH_DIR=
wcp.JS_DOMAIN=
wcp.WEB_AUTH_DOMAIN=
wcp.APICLIENT_CERT=
wcp.NOTIFY_URL=
wcp.TAKE_NOTIFY_URL=
wcp.NOTIFY_URL_REFUND=
接下来创建属性绑定配置类WCPConfig
@Configuration
@PropertySource("classpath:wcp-config.properties")
public class WCPConfig {
@Autowired
private Environment env;
@Autowired
private WCPConfigParamsYML wcpConfigParamsYML;
@Bean
public WCPConfigParams wcpConfigParams() {
WCPConfigParams params = new WCPConfigParams();
params.setAppId(env.getProperty("wcp.APP_ID"));
params.setAppSecret(env.getProperty("wcp.APPSECRET"));
params.setMuchId(env.getProperty("wcp.MCH_ID"));
params.setApiKey(env.getProperty("wcp.API_KEY"));
params.setRegisterDomain(env.getProperty("wcp.REGISTER_DOMAIN"));
params.setJsapiPaymentAuthDir(env.getProperty("wcp.JSAPI_PAYMENT_AUTH_DIR"));
params.setJsDomain(env.getProperty("wcp.JS_DOMAIN"));
params.setWebAuthDomain(env.getProperty("wcp.webAuthDomain"));
params.setApiclientCert(env.getProperty("wcp.APICLIENT_CERT"));
params.setNotifyUrl(env.getProperty("wcp.NOTIFY_URL"));
params.setTakeNotifyUrl(env.getProperty("wcp.TAKE_NOTIFY_URL"));
params.setNotifyUrlRefund(env.getProperty("wcp.NOTIFY_URL_REFUND"));
return params;
}
}
这里要使数据绑定生效,需要加上@PropertySource("classpath:wcp-config.properties")
指定配置文件路径,@Configuration
表示这是一个配置类,在项目启动时会注入到ioc容器中。
通过注入Environment类,使用该类的getProperty()方法获取配置文件中配置的数据,然后通过set将数据赋值给微信支付参数类的各属性,在wcpConfigParams
方法加上@Bean
注入到ioc容器中,项目启动的时候就会将数据填充到参数类中,在需要使用的地方注入该类就可以直接通过get方法获取参数。比如在我的一个controller层就是这样
@Controller
@Api(tags = "支付功能相关controller")
public class WxPayController {
@Autowired
private WCPConfigParams wcpConfigParams;
......
requestEntity.setNotifyUrl(wcpConfigParams.getTakeNotifyUrl());
}
2. yaml配置文件绑定
这种方式实际中用的更多,像spring boot的自动配置基本都是靠这种方式去做的。
也是先创建一个支付参数实体类WCPConfigParamsYML
@Component
@Data
@ConfigurationProperties("wx.pay")
public class WCPConfigParamsYML {
private String appId;
private String appSecret;
private String muchId;
private String apiKey;
private String registerDomain;
private String jsapiPaymentAuthDir;
private String jsDomain;
private String webAuthDomain;
private String apiclientCert;
private String notifyUrl;
private String takeNotifyUrl;
private String notifyUrlRefund;
}
这里和properties方式配置就有所区别了。多了两个注解@Component
和@ConfigurationProperties("wx.pay")
。@Component
的作用是将其作为一个Bean注入到ioc容器中,@ConfigurationProperties("wx.pay")
是指定其配置文件前缀名。这里@Component
不是必要的,不加也可以通过其他方式使用。
建好之后可以Ctrl+F9去build一下,主要是为了编译项目,生成spring-configuration-metadata.json,这样在yaml文件中配置属性时就会有提示。
这里的属性配置属于一种松散绑定,也就是说不需要精准对应属性名就可以完成绑定,一共四种模式:
Property | Note |
---|---|
acme.my-project.person.first-name | 羊肉串模式, 推荐在.properties或.yaml文件中使用 |
acme.myProject.person.firstName | 驼峰模式 |
acme.my_project.person.first_name | 下划线模式 |
ACME_MYPROJECT_PERSON_FIRSTNAME | 大写下划线模式 |
只要名字对应,使用哪种模式都能匹配到支付参数类中的属性。
然后就是在yaml文件中进行配置,配置时会有代码提示,这部分就不贴了。
需要使用时和properties方式一样。
@Autowired
private WCPConfigParamsYML wcpConfigParamsYML;
另外还有一种方式,如果不加@Component
注解,那么在需要使用的类上加@EnableConfigurationProperties({WCPConfigParamsYML.class})
注解,就可以在这个类中拿到配置的属性值了。
这种方式配置时还可以在支付参数类上加@Validated
注解启用参数校验,使用也比较简单,就不单独介绍了。
3. @ConfigurationProperties 和 @Value
这两个注解实现的功能其实一样,但是使用上有一些区别:
@ConfigurationProperties | @Value | |
---|---|---|
配置属性数量 | 多个 | 一个 |
松散绑定 | YES | Limit |
校验 | YES | NO |
spEL表达式 | NO | YES |
复杂类型绑定 | YES | NO |
YES | NO |
具体的就不一一介绍了,使用时多个属性最好用@ConfigurationProperties
,只有一个属性可以用@Value
。
下一篇: ES6的解构赋值实例详解