Spring boot外部配置(配置中心化)详解
前言
在项目中为了灵活配置,我们常采用配置文件,常见的配置文件就比如xml和properties,springboot允许使用properties和yaml文件作为外部配置。现在编译器对于yaml语言的支持还不够好,目前还是使用properties文件作为外部配置。
在spring cloud config出来之前, 自己实现了基于zk的配置中心, 杜绝了本地properties配置文件, 原理很简单, 只是重载了propertyplaceholderconfigurer的mergeproperties()
:
/** * 重载合并属性实现 * 先加载file properties, 然后并入zk配置中心读取的properties * * @return 合并后的属性集合 * @throws ioexception 异常 */ @override protected properties mergeproperties() throws ioexception { properties result = new properties(); // 加载父类的配置 properties mergeproperties = super.mergeproperties(); result.putall(mergeproperties); // 加载从zk中读取到的配置 map<string, string> configs = loadzkconfigs(); result.putall(configs); return result; }
这个实现在spring项目里用起来还是挺顺手的, 但是近期部分spring-boot项目里发现这种placeholder的实现跟spring boot的@configurationproperties(prefix = "xxx")
不能很好的配合工作,
也就是属性没有被resolve处理, 用@value的方式确可以读到, 但是@value配置起来如果属性多的话还是挺繁琐的, 还是倾向用@configurationproperties的prefix, 于是看了下spring boot的文档发现 propertysource
order:
* devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
* @testpropertysource annotations on your tests.
* @springboottest#properties annotation attribute on your tests.
* command line arguments.
* properties from spring_application_json (inline json embedded in an environment variable or system property)
* servletconfig init parameters.
* servletcontext init parameters.
* jndi attributes from java:comp/env.
* java system properties (system.getproperties()).
* os environment variables.
* a randomvaluepropertysource that only has properties in random.*.
* profile-specific application properties outside of your packaged jar (application-{profile}.properties and yaml variants)
* profile-specific application properties packaged inside your jar (application-{profile}.properties and yaml variants)
* application properties outside of your packaged jar (application.properties and yaml variants).
* application properties packaged inside your jar (application.properties and yaml variants).
* @propertysource annotations on your @configuration classes.
* default properties (specified using springapplication.setdefaultproperties).
不难发现其会检查java system propeties里的属性, 也就是说, 只要把mergerproperties读到的属性写入java system props里即可, 看了下源码, 找到个切入点
/** * 重载处理属性实现 * 根据选项, 决定是否将合并后的props写入系统属性, spring boot需要 * * @param beanfactorytoprocess * @param props 合并后的属性 * @throws beansexception */ @override protected void processproperties(configurablelistablebeanfactory beanfactorytoprocess, properties props) throws beansexception { // 原有逻辑 super.processproperties(beanfactorytoprocess, props); // 写入到系统属性 if (writepropstosystem) { // write all properties to system for spring boot enumeration<?> propertynames = props.propertynames(); while (propertynames.hasmoreelements()) { string propertyname = (string) propertynames.nextelement(); string propertyvalue = props.getproperty(propertyname); system.setproperty(propertyname, propertyvalue); } } }
为避免影响过大, 设置了个开关, 是否写入系统属性, 如果是spring boot的项目, 就开启, 这样对线上非spring boot项目做到影响最小, 然后spring boot的@configurationproperties
完美读到属性;
具体代码见: org.springframework.boot.context.properties.configurationpropertiesbindingpostprocessor
@override public object postprocessbeforeinitialization(object bean, string beanname) throws beansexception { configurationproperties annotation = annotationutils .findannotation(bean.getclass(), configurationproperties.class); if (annotation != null) { postprocessbeforeinitialization(bean, beanname, annotation); } annotation = this.beans.findfactoryannotation(beanname, configurationproperties.class); if (annotation != null) { postprocessbeforeinitialization(bean, beanname, annotation); } return bean; }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
推荐阅读
-
Spring Boot 配置随机数的技巧代码详解
-
详解Spring Boot Profiles 配置和使用
-
SpringBoot + Spring Security 基本使用及个性化登录配置详解
-
详解Spring Boot 属性配置和使用
-
Spring boot 添加jsp支持配置详解
-
Spring boot中@Conditional和spring boot的自动配置实例详解
-
Spring Boot Web应用程序配置详解
-
Spring Boot 配置随机数的技巧代码详解
-
详解Spring Boot下Druid连接池的使用配置分析
-
详解spring cloud config整合gitlab搭建分布式的配置中心