Spring boot外部配置(配置中心化)详解
|
前言 在项目中为了灵活配置,我们常采用配置文件,常见的配置文件就比如xml和properties,springboot允许使用properties和yaml文件作为外部配置。现在编译器对于yaml语言的支持还不够好,目前还是使用properties文件作为外部配置。 在Spring cloud config出来之前,自己实现了基于ZK的配置中心,杜绝了本地properties配置文件,原理很简单,只是重载了PropertyPlaceholderConfigurer的
/**
* 重载合并属性实现
* 先加载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的 也就是属性没有被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的 具体代码见:
@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,annotation);
}
return bean;
}
总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对编程小技巧的支持。 (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
