`
aa860326
  • 浏览: 95737 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

web应用生产环境properties文件自动更新

    博客分类:
  • J2EE
 
阅读更多

在我们的生产系统上,如果我们修改了properties中的一个配置项,如果想要这个配置生效,最简单的办法就是把这个应用重启。但是现实却不允许我们这样做。以下简单实现了一些代码,可以在修改配置项之后,做到自动加载这个配置的值。以下提供简单的思路和代码:

package com.busi.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;


public class PropertyUtil {
	
	private static final Logger LOG = Logger.getLogger(PropertyUtil.class);
	private static final String PROPERTIES_SUFFIX = ".properties";
	private static List<String> register = Collections.synchronizedList(new ArrayList<String>());
	private static Map<String, String> keyValues = new ConcurrentHashMap<>();
	private static Timer timer = new Timer(PropertyUtil.class.getName());
	private static final long DELAY_TIME = 5000; // 延迟加载时间(单位:ms)
	
	
	private static String getClassPath(){
		return PropertyUtil.class.getResource("/").getPath();
	}
	
	
	private static String getFileAboslutePath(String filename){
		StringBuffer buffer = new StringBuffer();
		buffer.append(getClassPath());
		buffer.append(filename);
		buffer.append(PROPERTIES_SUFFIX);
		return buffer.toString();
	}
	
	
	public static void register(String... filenames){
		for (String filename : filenames){
			if (!register.contains(filename)){
				register.add(filename);
				final TimerTask task = new PropertiesTask(filename);
				timer.schedule(task, 0, DELAY_TIME);
			}
		}
	}
	
	private static void loadProperties(String filename){
		InputStream is = null;
		try {
			String fileAbsolutePath = getFileAboslutePath(filename);
			is = new FileInputStream(fileAbsolutePath);
			Properties properties = new Properties();
			properties.load(is);
			is.close();
			if (!properties.isEmpty()){
				Set<Entry<Object, Object>> set = properties.entrySet();
				Iterator<Map.Entry<Object, Object>> it = set.iterator();
				String key = null;
				String value = null;
				while(it.hasNext()){
					Entry<Object, Object> entry = it.next();
					key = String.valueOf(entry.getKey());
					value = String.valueOf(entry.getValue());
					keyValues.put(key, value);
				}
				LOG.debug("#loadProperties() Properties文件内容:"+keyValues);
			}
			
		} catch (Exception e){
			LOG.error("#loadProperties() Properties文件加载异常", e);
		}
	}
	
	public static String getStrValue(String key, String defaultValue){
		String value = keyValues.get(key);
		return (null == value)?defaultValue:value.trim();
	}
	
	public static Integer getIntValue(String key, Integer defaultValue){
		String value = keyValues.get(key);
		return (null == value)?defaultValue:Integer.valueOf(value.trim());
	}
	
	static class PropertiesTask extends TimerTask{
		
		private String filename;
		private long lastModified;
		
		public PropertiesTask(String filename){
			super();
			this.filename = filename;
			this.lastModified = 0l;
		}
		
		public void run() {
			try {
				File file = new File(getFileAboslutePath(filename));
				if (!file.exists()){
					LOG.info(filename+"文件不存在!");
				}
				long newLastModified = file.lastModified();
				if (newLastModified > lastModified){
					LOG.info("Properties文件["+filename+"]有变动,重新加载!");
					lastModified = newLastModified;
					loadProperties(filename);
				}
			} catch (Exception e){
				LOG.error("#run() Properties文件处理异常", e);
			}
		}
	}
	
	public static void main(String[] args) throws Exception{
		PropertyUtil.register("system", "test");
		Thread.sleep(200l);
		System.out.println(PropertyUtil.getStrValue("platform.name", "service"));
	}
}



 上诉代码还有一些不足的地方,欢迎拍砖。

 --------------------------------------------------分割线--------------------------------------------------------

IT行业我认为是个高危的行业,“996”模式在互联网公司很常见,每每出现过劳死几乎是这个行当。因此我们应该具备一定风险意识,给自己投资一定的风险保证金:https://ssl.700du.cn/shopping/18611517897。给自己和家人一个保障。

分享到:
评论

相关推荐

    Struts2属性文件详解

    指定Web应用的默认编码集.该属性对于处理中文请求参数非常有用,对于获取中文请求参数值,应该将该属性值设置为GBK或者GB2312; 提示: 当设置该参数为GBK时,相当于调用HttpServletRequest的setCharacterEncoding方法. ...

    jcseg,Jcseg 是基于 mmseg 算法的一个轻量级中文分词器,同时集成了关键字提取,关键短语提取,关键句子提取和文章自动摘要等功能,并且提供了一个基于 Jetty 的 web 服务器,方便各大语言直接 http 调用,同时提供了最新版本的 lucene, solr, elasticsearch 的分词接口!.zip

    Jcseg是基于 mmseg 算法的一个轻量级中文分词器,...Jcseg自带了一个 jcseg.properties 文件用于快速配置而得到适合不同场合的分词应用,例如:最大匹配词长,是否开启中文人名识别,是否追加拼音,是否追加同义词等!

    Struts2\constant应用

    该属性指定Velocity框架所需的velocity.properties文件的位置。该属性的默认值为velocity.properties。 struts.velocity.contexts 该属性指定Velocity框架的Context位置,如果该框架有多个Context,则多个...

    belladati-sdk-demo-web:使用BellaDati SDK的演示Web应用程序

    BellaDati SDK演示Web应用程序 该存储库包含一个使用的演示Web应用程序。 它连接到BellaDati云服务,并演示显示和过滤来自您域的报告。 检出和配置 将此存储库克隆到您选择的目录中。 如果您使用的是Eclipse,则...

    SpringBoot学习视频

    尚硅谷_SpringBoot_配置-properties配置文件编码问题 尚硅谷_SpringBoot_配置-@ConfigurationProperties与@Value区别 尚硅谷_SpringBoot_配置-@PropertySource、@ImportResource、@Bean 尚硅谷_SpringBoot_配置-配置...

    尚硅谷springboot视频(上)

    尚硅谷_SpringBoot_配置-properties配置文件编码问题 尚硅谷_SpringBoot_配置-@ConfigurationProperties与@Value区别 尚硅谷_SpringBoot_配置-@PropertySource、@ImportResource、@Bean 尚硅谷_SpringBoot_配置-配置...

    SpringBoot启动过程-mind版.md

    Spring Boot的启动过程可以分为以下几个关键步骤: 1. **加载配置:** Spring Boot会读取项目中的配置文件(如`application....5. **启动内嵌服务器:** 如果应用是一个Web应用,Spring Boot会根据配置自动启动内

    将 Flex 集成到 Java EE 应用程序的最佳实践(完整源代码)

    默认地,Flex Builder 将会把生成的 Flash 文件放到 EmployeeMgmt-Server 项目的 web/EmployeeMgmt-Flex-debug 目录下。 一个 Flex Project 的目录结构如下: 图 5. Flex 工程的目录结构 用 Flex Builder 做出...

    128元尚硅谷Java视频教程_SpringBoot视频教程(上)核心技术篇

    12、尚硅谷_SpringBoot_配置-properties配置文件编码问题 13、尚硅谷_SpringBoot_配置-@ConfigurationProperties与@Value区别 14、尚硅谷_SpringBoot_配置-@PropertySource、@ImportResource、@Bean 15、尚硅谷_...

    尚硅谷Spring boot核心技术篇(上)

    09、尚硅谷_SpringBoot_配置-yaml简介 10、尚硅谷_SpringBoot_配置-yaml语法 11、尚硅谷_SpringBoot_配置-yaml配置文件值获取 12、尚硅谷_SpringBoot_配置-properties配置文件编码问题 13、尚硅谷_SpringBoot_配置-@...

    unified-e2e:使用Cucumber和ReportPortal进行本机和Web自动化的End-2-End框架

    报告将被上载到reportportal.io,您需要单独设置报告,并在src / test / resources / reportportal.properties文件中提供服务器详细信息,或者使用以下环境变量提供文件的路径: REPORT_PORTAL_FILE 使用的技术堆栈 ...

    R2高性能数据库连接池v1.6源码

    应用时,先用rar打开jar包,拷贝r2.properties文件到class目录,并修改参数。 本包需要用到log4j,请在调用时确保存在log4j的jar包。 单池调用方式为Connection conn = R2PoolUtil.getStaticPool().getConnection...

    R2高性能数据库连接池v1.7源码

    应用时,先用rar打开jar包,拷贝r2.properties文件到class目录,并修改参数。 本包需要用到log4j,请在调用时确保存在log4j的jar包。 单池调用方式为Connection conn = R2PoolUtil.getStaticPool().getConnection();...

    +Flex+集成到+Java+EE+应用程序的最佳实践(完整源代码)

    这个强类型的 RemoteObject 最好能通过 Java EE 应用的 FlexService 接口自动生成,这样,就无需再维护 RemoteObject 的定义。 为了能完成自动生成 RemoteObject 对象,我编写了一个 Java2ActionScript 的 Ant ...

    Java SpringBoot课件+源码视频教程

    12、_SpringBoot_配置-properties配置文件编码问题 13、_SpringBoot_配置-@ConfigurationProperties与@Value区别 14、_SpringBoot_配置-@PropertySource、@ImportResource、@Bean 15、_SpringBoot_配置-配置文件...

    JAVA毕业设计之springboot121编程训练系统设计与实现(springboot+mysql)完整源码.zip

    最后,我们需要在application.properties文件中配置数据库连接信息,以及一些其他的应用设置。这个编程训练系统的完整源代码已经打包成一个.zip文件,可以直接下载使用。通过这个系统,你可以轻松地管理你的编程课程...

    Jcseg+Java中文分词器

    Jcseg自带了一个 jcseg.properties文件用于快速配置而得到适合不同场合的分词应用,例如:最大匹配词长,是否开启中文人名识别,是否追加拼音,是否追加同义词等! Jcseg核心功能: 中文分词:mmseg算法 + Jcseg ...

    citrix 中文管理操作手册

    更新文件类型关联 52 配置备用配置文件 53 将参数传递给已发布的应用程序 53 减少流应用程序的用户权限 53 配置应用程序限制和重要性 54 配置已发布应用程序的音频和加密选项 54 配置应用程序外观 56 禁用或启用已...

    MiinCMP 企业网站系统 v1.0.5 新浪云版.zip

    3)文档存储API更新,同时支持本地文件IO和数据库存储.   MiinCMP是一款开源企业网站系统,除可运行于256M左右100元的国内IDC外,MiinCMP近期开发了面向新浪云的版本,该版本可将网站免费布署到新浪云SAE上。   ...

    Android代码-jcseg

    Jcseg自带了一个 jcseg.properties文件用于快速配置而得到适合不同场合的分词应用,例如:最大匹配词长,是否开启中文人名识别,是否追加拼音,是否追加同义词等! Jcseg核心功能: &gt; 中文分词:mmseg算法 Jcseg ...

Global site tag (gtag.js) - Google Analytics