Java模块 -- WatchService监听服务

有过纯后台开发或者写过后台小工具的童鞋,肯定都遇到过这样的场景:

程序部署在测试环境或生产环境,这时候需要修改配置文件的一个参数,正常情况下,需要我们重启程序,有时候,参数调优,需要重启很多次,这就比较讨厌了...

最近无意中看到两篇博文,参考着他们,将这个小工具写好了。

两篇博文,单一的看,并不能满足需求。


http://blog.csdn.net/buptwds/article/details/44860625

这篇博文是监控目录下文件的状态。


http://blog.csdn.net/LoveJavaYDJ/article/details/73521726

这篇博文单纯的监控某个文件,并且要是src资源目录下的配置文件。

尝试过,修改博文中提供的代码,但感觉还是不行,于是想着将这两篇结合一下。


首先监控conf目录下所有的配置文件,有改动了,获取到该文件的文件名,然后直接重新读取就行。


举一个实际的栗子:

一个后台程序启动之后,配置类首先加载、读取conf目录下所有的配置文件,到内存中(第一次加载),这个配置类是单例的。

接着程序继续执行,调用监控配置文件方法(后台线程),然后完成初始化动作,然后运行一段时间后,修改配置文件参数,

当感知到配置文件修改之后,自动重新加载到内存中。


下面我们直接看代码:

package com.tools;

import java.io.File;
import java.io.FileInputStream;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Properties;

/**
* 监控conf目录下文件是否改动
* 
* http://blog.csdn.net/buptwds/article/details/44860625
* http://blog.csdn.net/LoveJavaYDJ/article/details/73521726
* 
* 需求场景:程序启动;配置类单例,第一次加载配置文件;接着开始监控,如果配置文件修改,重新加载
* 
* @author CYX
*
*/
public class WatchFile {

private static WatchService watchService;
private static Properties properties = new Properties();
private static String filePath;

public void watch() {

	// conf目录全路径
	filePath = (new File("conf").getAbsolutePath());

	try {

		// 获取文件系统的WatchService对象
		watchService = FileSystems.getDefault().newWatchService();
		// 监听'filePath'是否修改;register()方法后面监听事件种类还可以增加。
		Paths.get(filePath).register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);

	} catch (Exception e) {
		e.printStackTrace();
	}

	// 设置后台线程
	Thread watchThread = new Thread(new Runnable() {

		@Override
		public void run() {

			while (true) {

				try {

					// 获取下一个文件改动事件
					WatchKey key = watchService.take();

					for (WatchEvent<?> event : key.pollEvents()) {

						System.out.println(filePath + "/" + event.context() + " --> " + event.kind());
						System.out.println("重新加载 : " + filePath + "/" + event.context());
						properties.load(new FileInputStream(new File(filePath + "/" + event.context())));

					}

					// 重设WatchKey
					boolean valid = key.reset();

					// 如果重设失败,退出监听
					if (!valid) {
						break;
					}

				} catch (Exception e) {
					e.printStackTrace();
				}

			}
		}

	});

	// 设置为后台守护线程
	watchThread.setDaemon(true);
	watchThread.start();

}

/**
 * 模拟测试
 * 
 * @param args
 * @throws Exception
 */
public static void main(String[] args) throws Exception {

	// 程序启动;配置类第一次加载配置文件(配置类为单例)。
	properties.load(new FileInputStream(new File("./conf/sysConfig2.properties")));
	System.out.println("username1 : " + properties.get("username"));
	System.out.println("age1 : " + properties.get("age"));

	// 开启监听程序,如有改动,则更新对象
	WatchFile w = new WatchFile();
	w.watch();

	// 假装做一些事情,延迟8秒。
	Thread.sleep(8000);

	// 延期之后,重新读取配置类中的参数。
	System.out.println("username2 : " + properties.get("username"));
	System.out.println("age2 : " + properties.get("age"));
}

}


代码就这些,就不上传Demo了...


测试结果:



项目结构



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值