spring: 加载远程配置
通常在spring应用中,配置中的properties文件,都是打包在war包里的,部署规模较小,只有几台服务器时,这样并没有什么大问题。如果服务器多了,特别是集群部署时,如果要修改某一项配置,得重新打包、部署,一台台机器改过去,十分麻烦。
看了Spring-Cloud项目,深受启发,Spring-Cloud把配置文件放在远程的git或svn这类云平台之上,所有应用启动时从云上获取配置,配置需要修改时,直接修改git上的配置即可,十分方便,但是这个项目并不简单,新概念太多,需要一定时间熟悉。
借鉴一下spring-cloud的理念,我们可以把properties文件放在局域网的网络位置上,启动时远程加载即可,核心实现类:
package org.demo; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.StringUtils;
import java.util.Properties; /**
* load remote properties
*/
public class RemoteProperties implements InitializingBean, FactoryBean<Properties> { Logger logger = LogManager.getLogger(); private String url = null; private Properties properties = new Properties(); @Override
public Properties getObject() throws Exception {
return properties;
} @Override
public Class<?> getObjectType() {
return properties.getClass();
} @Override
public boolean isSingleton() {
return true;
} @Override
public void afterPropertiesSet() throws Exception {
loadProperty();
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
} private void loadProperty() {
if (StringUtils.isEmpty(url)) return;
logger.debug("loading remote properties:" + url);
String content = HttpUtil.get(url);
logger.debug("remote properties conent:" + content);
String[] lines = content.replaceAll("\r", "").split("\n");
for (String line : lines) {
if (!StringUtils.isEmpty(line)) {
String[] arr = line.split("=");
properties.put(arr[0].trim(), arr[1].trim());
}
}
}
}
代码不复杂,增加了一个url属性,用来获取远程属性文件的位置,然后在loadProperty里,发起http的get请求,把属性文件的内容拿回来,存储到本地properties变量中。使用时,配置里这么写:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <!-- during developing, you can uncomment this to load local properties -->
<!-- <property name="location" value="application.properties"/> --> <property name="properties">
<bean id="remoteProperties" class="org.demo.RemoteProperties"
p:url="http://172.21.12*.**/config/dev/application.properties"/>
</property>
</bean> <bean class="org.demo.Foo" p:name="${name}"></bean> </beans>
注意13-16行,这里指定远程属性的位置,在开发阶段,为了方便调试,可以把上面注释的部分去掉,这样相当于直接使用本地properties文件。
我在淘宝Code,上传了一个示例程序spring-load-remote-config,方便大家参考。
当然,其实从文件路径或http网址远程属性文件,Spring本身就支持的,配置示例如下:
<bean id="propertiesFactoryBean1"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location"
value="http://172.21.*.*/config/dev/application.properties" />
</bean> <bean id="propertiesFactoryBean2"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location"
value="file:D:\test\resources\application.properties" />
</bean>
既然Spring已经支持了,还研究这个干嘛?
有些要求更高的场景,比如配置放在redis缓存里,或数据库里,或者存储在zookeeper节点上,或者属性的值必须加密存储,这些spring默认的实现是不够的,明白上面的原理后,只要把loadProperty()方法的实现按需要修改即可。
注:如果把远程属性文件加载回来以后,还要做些后续处理,比如解密处理,RemoteProperties类的isSingleton()方法记得要返回false,否则之前的属性值会因为单例模式而缓存,始终返回的是解密前的原始值。
更进一步探讨:如果在远程服务器,写一个小程序监听配置文件变化,然后结合ZooKeeper的订阅、通知机制,子应用监听到配置变化时,调用ApplicationContext.refresh()方法,刷新上下文环境,理论上讲,应用连重启都不需要。
spring: 加载远程配置的更多相关文章
- spring加载配置文件
spring加载配置文件 1.把applicationContext.xml直接放在WEB-INF/classes下,spring会采用默认的加载方式2.采用在web.xml中配置ContextLoa ...
- Spring加载xsd引起的问题小记
前言 最近要把之前写好的监控系统加上报警功能,就是通过rpc调用发短信发邮件的服务发送报警信息.发短信发邮件的功能是通过dubbo管理提供的.自然使用这些服务就难免用到spring.而我这又是一个st ...
- jQuery.ajax( options ) : 通过 HTTP 请求加载远程数据
jQuery.ajax( options ) : 通过 HTTP 请求加载远程数据 这个是jQuery 的底层 AJAX 实现.简单易用的高层实现见 $.get, $.post 等. $.ajax() ...
- iOS Cordova 加载远程界面
老大说,我们的项目要hybrid,要实现1.html能调用native:2.本地html调用本地html界面:3.能加载远程界面..... 因为我的项目是已有的(以下简称 项目),所以是要在已有的项目 ...
- 监听spring加载完成后事件
有这个想法是在很早以前了,那时的我没有接触什么缓存技术,只知道hibernate有个二级缓存.没有用过memcache,也没有使用过redis. 只懂得将数据放到数组里或者集合里,一直不去销毁它(只有 ...
- spring加载资源文件中classpath*与classpath的区别
在spring和MyBatis继承的时候,配置mapperLocations.一开始配置是这样的. 需要加载路径为com/thomas/base/mapper和com/thomas/bu/mapper ...
- Spring加载流程源码分析03【refresh】
前面两篇文章分析了super(this)和setConfigLocations(configLocations)的源代码,本文来分析下refresh的源码, Spring加载流程源码分析01[su ...
- Spring加载properties文件的两种方式
在项目中如果有些参数经常需要修改,或者后期可能需要修改,那我们最好把这些参数放到properties文件中,源代码中读取properties里面的配置,这样后期只需要改动properties文件即可, ...
- springMVC加载远程freemarker模板文件
在一个大网站里,有很多子域名,也就是有很多子系统,这些子系统由不同的团队负责,对整个网站的风格的风格至少得要是一致的(最基本的页头.页尾必须一致),这个时候得提供一份统一的页头.页尾以及公共的JS.c ...
随机推荐
- [转]android笔记--Intent和IntentFilter详解
Intent用于启动Activity, Service, 以及BroadcastReceiver三种组件, 同时还是组件之间通信的重要媒介. 使用Intent启动组件的优势1, Intent为组件的启 ...
- HTML5气泡悬浮框(已经加上完整文件)
源文件链接:http://pan.baidu.com/s/1pKHlNSn 设计气泡悬浮框 1.在网页设计中,气泡悬浮框常常用于页面中为某些对象显示提示信息,恰当地使用气泡悬浮框能够使网页布局更加完美 ...
- NPOI对Excel的操作(Sheet转DataTable、List<T>)
通过NPOI对Excel进行操作,这里主要是读取的操作.封装到ExcelHelper操作类中. 1 using System.Collections.Generic; 2 using NPOI.HSS ...
- github代码上传之命令提交
Git GUI的用法比较简单,随便弄弄就可以将本地git库中的代码提交到远端github服务器,所以想把Git bash这玩意儿的操作流程快速过一遍,主要是做个笔记,以后忘记了可以看看怎么操作的. 首 ...
- jQuery中find和filter的区别
本文来自:http://blog.csdn.net/woshixuye/article/details/7255260 这是jQuery里常用的2个方法. 他们2者功能是完全不同的,而初学者往往会被误 ...
- Spring AOP 动态代理 缓存
Spring AOP应用:xml配置及注解实现. 动态代理:jdk.cglib.javassist 缓存应用:高速缓存提供程序ehcache,页面缓存,session缓存 项目地址:https://g ...
- Python基本语法[二],python入门到精通[四]
在上一篇博客Python基本语法,python入门到精通[二]已经为大家简单介绍了一下python的基本语法,上一篇博客的基本语法只是一个预览版的,目的是让大家对python的基本语法有个大概的了解. ...
- oracle学习笔记系列------oracle 基本操作之基本函数的用法
--创建一个accout账户表 CREATE TABLE account( id ) NOT NULL, recommender_id ), login_name ) NOT NULL, login_ ...
- 白话debounce和throttle
遇到的问题 在开发过程中会遇到频率很高的事件或者连续的事件,如果不进行性能的优化,就可能会出现页面卡顿的现象,比如: 鼠标事件:mousemove(拖曳)/mouseover(划过)/mouseWhe ...
- Windows Azure 虚拟机的IP地址操作
Windows Azure上的一个虚拟机对应两个IP地址,VIP和DIP. VIP,公网IPv4地址,动态分配.虚拟机停止(deallocate,在管理控制台上关机或者使用PowerShell关机)后 ...