JAVA项目监听文件是否发生变化

一.spring容器都初始化完成之后做操作

package com.bijian.study.listener;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.web.context.support.XmlWebApplicationContext;

import com.bijian.monitor.FileMonitor;

public class ContextFileListener implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private FileMonitor fileMonitor;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if(event.getSource() instanceof XmlWebApplicationContext){
            if(((XmlWebApplicationContext)event.getSource()).getDisplayName().equals("Root WebApplicationContext")){
                try {
                    fileMonitor.monitor();
                    fileMonitor.start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

二.applicationContext.xml添加配置

<bean  />  
<bean >  
        <property name="alterationListener" ref="fileListener"/>  
        <property name="filePath" value="D:/SVN/"/>  
</bean>
    
<bean class="com.bijian.study.listener.ContextFileListener"/>

三.添加文件监听 FileMonitor、FileListener 可看资料commons-io-2.4

package com.bijian.study.monitor;

import java.io.File;

import org.apache.commons.io.monitor.FileAlterationListener;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;

public class FileMonitor {

    private FileAlterationMonitor monitor = null;

    private String filePath;
    private FileAlterationListener alterationListener;
    private long intervalTime = 10000L;

    public FileMonitor(long interval) throws Exception {
        monitor = new FileAlterationMonitor(interval);
    }

    public FileMonitor() throws Exception {
        monitor = new FileAlterationMonitor(intervalTime);
    }

    public void monitor(String path, FileAlterationListener listener) {
        FileAlterationObserver observer = new FileAlterationObserver(new File(path));
        monitor.addObserver(observer);
        observer.addListener(listener);
    }

    public void monitor() {
        FileAlterationObserver observer = new FileAlterationObserver(new File(filePath));
        monitor.addObserver(observer);
        observer.addListener(alterationListener);
    }

    public void stop() throws Exception {
        monitor.stop();
    }

    public void start() throws Exception {
        monitor.start();
    }

    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    public FileAlterationListener getAlterationListener() {
        return alterationListener;
    }

    public void setAlterationListener(FileAlterationListener alterationListener) {
        this.alterationListener = alterationListener;
    }

    public long getIntervalTime() {
        return intervalTime;
    }

    public void setIntervalTime(long intervalTime) {
        this.intervalTime = intervalTime;
    }
}
package com.bijian.study.listener;

import java.io.File;

import org.apache.commons.io.monitor.FileAlterationListener;
import org.apache.commons.io.monitor.FileAlterationObserver;

public class FileListener implements FileAlterationListener {

    @Override
    public void onStart(FileAlterationObserver observer) {
        // TODO Auto-generated method stub
        System.out.println("onStart()");

    }

    @Override
    public void onDirectoryCreate(File directory) {
        // TODO Auto-generated method stub
        System.out.println("onDirectoryCreate()");
    }

    @Override
    public void onDirectoryChange(File directory) {
        // TODO Auto-generated method stub
        System.out.println("onDirectoryChange()");
    }

    @Override
    public void onDirectoryDelete(File directory) {
        // TODO Auto-generated method stub
        System.out.println("onDirectoryDelete()");
    }

    @Override
    public void onFileCreate(File file) {
        // TODO Auto-generated method stub
        System.out.println("onFileCreate()");
    }

    @Override
    public void onFileChange(File file) {
        // TODO Auto-generated method stub
        System.out.println("onFileChange()");
    }

    @Override
    public void onFileDelete(File file) {
        // TODO Auto-generated method stub
        System.out.println("onFileDelete()");
    }

    @Override
    public void onStop(FileAlterationObserver observer) {
        // TODO Auto-generated method stub
        System.out.println("onStop()");
    }
}

至此完成启动项目,在指定文件夹D:/SVN/下增加、修改、删除文件都会触发相关方法。

附:解决onApplicationEvent方法被执行两次以上的问题

原因:

  在web 项目中(spring mvc),系统会存在两个容器,一个是root application context ,另一个就是我们自己的 projectName-servlet context(作为root application context的子容器)。在一个类里面实现了ApplicationListener接口,用于在初始化完成后做一些事情,但是Debug或输出日志,发现它执行了3次,其中一次是Spring 框架初始化时执行,另外两次是在项目启动成功后,加载Spring-MVC时执行的。

解决方法:

  1.根据对象值来告诉定时器只执行一次

  通过打 breakpoint看到,这两次执行中,onApplicationEvent(ContextRefreshdEvent event)方法中的 event对象值不同,第一次是 Root WebApplicationContext , 据此可以根据对象值来告诉定时器只执行一次即可,如如上实例所示,在这我System.out.println输出((XmlWebApplicationContext)event.getSource()).getDisplayName()。

package com.bijian.study.listener;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.web.context.support.XmlWebApplicationContext;

import com.bijian.study.monitor.FileMonitor;

public class ContextFileListener implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private FileMonitor fileMonitor;
    
    private static boolean isStart = false;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if(event.getSource() instanceof XmlWebApplicationContext){
            System.out.println(((XmlWebApplicationContext)event.getSource()).getDisplayName());
            if(((XmlWebApplicationContext)event.getSource()).getDisplayName().equals("Root WebApplicationContext")){
                try {
                    fileMonitor.monitor();
                    fileMonitor.start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

  System.out.println(((XmlWebApplicationContext)event.getSource()).getDisplayName());输出的内容如下所示:

Root WebApplicationContext
WebApplicationContext for namespace 'springMVC-servlet'
WebApplicationContext for namespace 'springMVC-servlet'

  2.使用一个类变量isStart,控制只执行一次

package com.bijian.study.listener;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.web.context.support.XmlWebApplicationContext;

import com.bijian.study.monitor.FileMonitor;

public class ContextFileListener implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private FileMonitor fileMonitor;
    
    private static boolean isStart = false;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {

         if (!isStart) {
            isStart = true;
            try {
                fileMonitor.monitor();
                fileMonitor.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
         }
    }
}

  

参考文章:http://blog.csdn.net/dailuwen/article/details/52129165

http://www.oschina.net/question/2293507_2201818?sort=default

http://www.tuicool.com/articles/Frem2u