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变量中。使用时,配置里这么写:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:p="http://www.springframework.org/schema/p"
 5        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 6
 7     <bean id="propertyPlaceholderConfigurer"
 8           class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
 9
10         <!-- during developing, you can uncomment this to load local properties -->
11         <!-- <property name="location" value="application.properties"/> -->
12
13         <property name="properties">
14             <bean id="remoteProperties" class="org.demo.RemoteProperties"
15                   p:url="http://172.21.12*.**/config/dev/application.properties"/>
16         </property>
17     </bean>
18
19     <bean class="org.demo.Foo" p:name="${name}"></bean>
20
21 </beans>

注意13-16行,这里指定远程属性的位置,在开发阶段,为了方便调试,可以把上面注释的部分去掉,这样相当于直接使用本地properties文件。

我在淘宝Code,上传了一个示例程序spring-load-remote-config,方便大家参考。

更进一步探讨:如果在远程服务器,写一个小程序监听配置文件变化,然后结合ZooKeeper的订阅、通知机制,子应用监听到配置变化时,调用ApplicationContext.refresh()方法,刷新上下文环境,理论上讲,启用连重启都不需要。

  

时间: 2024-10-31 18:00:04

spring: 加载远程配置的相关文章

(Spring加载xml时)org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element &#39;beans&#39;.

ApplicationContext ctx = new ClassPathXmlApplicationContext("test.xml");报错 在启动Spring时,报以下错误,如图: 原因是在xml中spring的xsd的版本配置的不一致,我使用的是spring-2.5.6,但配置文件中配的是3.0.改成如下即可: [xhtml] view plain copy <?xml version="1.0" encoding="UTF-8"

spring加载jar包中多个配置文件(转)

转自:http://evan0625.iteye.com/blog/1598366 在使用spring加载jar包中的配置文件时,不支持通配符,需要一个一个引入,如下所示: Java代码 <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:beanconfigs/applicationContext_1.xml, classpath*:

spring加载配置文件

spring加载配置文件 1.把applicationContext.xml直接放在WEB-INF/classes下,spring会采用默认的加载方式2.采用在web.xml中配置ContextLoaderListenera或ContextLoaderServlet指定加载路径方式.3 通过ClassPathXmlApplicationContext或XmlWebApplicationContext代码动态加载!

spring加载jar包中的多个配置文件[转载]

在使用spring加载jar包中的配置文件时,不支持通配符,需要一个一个引入,如下所示: Java代码 <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:beanconfigs/applicationContext_1.xml, classpath*:beanconfigs/applicationContext_2.xml, ...

【转载】Spring加载resource时classpath*:与classpath:的区别

免责声明:     本文转自网络文章,转载此文章仅为个人收藏,分享知识,如有侵权,请联系博主进行删除.     原文作者:kyfxbl     原文地址: spring配置中classpath和classpath*的区别   在spring配置文件里,可以用classpath:前缀,来从classpath中加载资源  比如在src下有一个jdbc.properties的文件,可以用如下方法加载: <bean id="propertyConfigurer" class="

is not mapped问题,Spring加载jar中配置文件

错误如下: org.hibernate.hql.ast.QuerySyntaxException: Content is not mapped [select new Content (t.id,t.name,t.values,t.systemType,t.type,t.sortnumber) from Content t where 1=1 and t.type = ? and t.systemType = ? order by t.sortnumber desc ] at org.hiber

springMVC加载远程freemarker模板文件

在一个大网站里,有很多子域名,也就是有很多子系统,这些子系统由不同的团队负责,对整个网站的风格的风格至少得要是一致的(最基本的页头.页尾必须一致),这个时候得提供一份统一的页头.页尾以及公共的JS.css等内容,但如果是直接给源代码(ftl/js/css)的形式,对于后期的升级维护必然增加不必要的麻烦,必须得只有一个维护这个代码. freemarker提供了远程模板加载的功能,在各个业务方里就像使用本地的模板一样使用远程的统一的模板代码. 1.编写自定义的模板加载器(继续freemarker的接

Spring加载xsd引起的问题小记

前言 最近要把之前写好的监控系统加上报警功能,就是通过rpc调用发短信发邮件的服务发送报警信息.发短信发邮件的功能是通过dubbo管理提供的.自然使用这些服务就难免用到spring.而我这又是一个storm工程,为了方便,我都是用maven-shade-plugin把所有依赖的jar打到一起. 在本地运行没有任何问题,但已提交到在线环境的storm(在线环境是没法连接到外网的),就会报错: spring cvc-elt.1: Cannot find the declaration of elem

iOS Cordova 加载远程界面

老大说,我们的项目要hybrid,要实现1.html能调用native:2.本地html调用本地html界面:3.能加载远程界面..... 因为我的项目是已有的(以下简称 项目),所以是要在已有的项目里加上cordova,只是在加载远程界面这个搞了好久,伤~~~ 配置cordova 人太懒,看这里的博客吧.或者自行搜索,网上一大把. 加载远程界面 看了好几篇博客,都不行. a.ios cordova如何加载远程界面? b.Cordoval在iOS中的运用整理 ...... 不行 然后我试着用$