Java动态修改配置即时生效的方式WatchService

  
  

这种方式仅适合于比较小的项目,例如只有一两台服务器,而且配置文件是可以直接修改的,例如Spring mvc以战争包的形式部署,可以直接修改资源中的配置文件。如果是弹簧启动项目,还想用这种方式的话,就要引用一个外部可以编辑的文件,比如一个固定的目录,因为弹簧引导大多数以jar包部署,打到包里的配置文件没办法直接修改。如果是比较大的项目,最好还是用配置中心,例如携程的阿波罗,领事等。

     

<强>原始方式

  

原始方式指的是每次要修改配置的时候,都要重新打包发布或者重启服务器。

  

假设我们用spring mvc开发,开发完成后打成战争包部署到tomcat上,如果这时我们修改一个短信接口地址。

  

我们要做如下操作:

  

1,打开配置文件,修改配置信息;

  

2,编译打包;

  

3,停止tomcat,删除旧的项目目录;

  

4,将新战争的包放到webapps,启动tomcat。

  

当然,可以直接在tomcat中找到这个项目的配置文件,然后修改,但同样需要重启tomcat。

  

如果只是单纯做开发或者测试,除了有点浪费时间外,当然可以接受。那么,既不想浪费时间又不想重启tomcat呢,有没有办法呢。这就轮到本文介绍的这种方式了。

  

<强> WatchService方式

  

Java提供了WatchService接口,这个接口是利用操作系统本身的文件监控器对目录和文件进行监控,当被监控对象发生变化时,会有信号通知,从而可以高效的发现变化。

  

这种方式大致的原理:先根据操作系统新一个监控器(WatchService),然后选择要监控的配置文件所在目录或文件,然后订阅要监控的事件,例如创建,删除,编辑,最后向被监控位置注册这个监控器。一旦触发对应我们所订阅的事件时,执行相应的逻辑即可。

  

先上代码吧,这是在一个spring mvc项目里,监控的是资源目录。

        @   公开课ConfigWatcher {      私有静态最终日志记录器=LoggerFactory.getLogger (ConfigWatcher.class);      私有静态WatchService WatchService;      @PostConstruct   公共空间init () {   logger.info(“启动配置文件监控器”);   尝试{   .newWatchService watchService=FileSystems.getDefault () ();   网址URL=ConfigWatcher.class.getResource (“/?;   路径路径=Paths.get (url.toURI ());   路径。注册(watchService StandardWatchEventKinds。修改,StandardWatchEventKinds.ENTRY_CREATE);   }捕捉(异常e1) {   e1.printStackTrace ();   }/* *   *启动监控线程   */线程watchThread=新线程(新watchThread ());   watchThread.setDaemon(真正的);   watchThread.start ();/* *注册关闭钩子*/线程钩子=新线程(新Runnable () {   @Override   公共空间run () {   尝试{   watchService.close ();   }捕捉(IOException e) {   e.printStackTrace ();   }   }   });   Runtime.getRuntime () .addShutdownHook(钩);   }      公共类WatchThread实现Runnable {   @Override   公共空间run () {   而(真){   尝试{//尝试获取监控池的变化,如果没有则一直等待   WatchKey WatchKey=watchService.take ();   (WatchEvent<& # 63;比;事件:watchKey.pollEvents ()) {   .toString字符串editFileName=event.context () ();   logger.info (editFileName);/* *   *重新加载配置   */}   watchKey.reset();//完成一次监控就需要重置监控器一次   }捕捉(异常e) {   e.printStackTrace ();   }   }   }   }   }      

代码非常简单,一看就懂,在项目启动的时候,用FileSystems.getDefault () .newWatchService()创建一个WatchService,这是根据操作系统来的。然后获取资源目录的URL,并由此获取路径,然后调用路径对象的注册方法,注册监控器,订阅了编辑和创建事件。事件在StandardWatchEventKinds类中定义,共有四种:

  

1, StandardWatchEventKinds #溢出

  

2, StandardWatchEventKinds # ENTRY_CREATE

  

3, StandardWatchEventKinds # ENTRY_DELETE

  

4, StandardWatchEventKinds #修改

  

然后单独启动了一个WatchThread线程来处理变化逻辑,在一个虽然无限循环中调用带()方法,直到有变化发生,一旦是我们监控的配置文件发生了变化,则调用我们的逻辑重新加载配置。另外,每次有变化发生后,要调用watchKey.reset()方法来重置监控器。

  

最后,还要注册一个钩,在jvm关闭的时候可以关闭监控器。

  

有了这种方式,当我们有一些配置变化的时候,就可以直接到tomcat下修改配置文件,不用重启就可以生效了。

Java动态修改配置即时生效的方式WatchService