一直使用tomcat开发,只要将<Context docBase="MyTest" path="/MyTest" reloadable="true" /></Host>中的reloadable属性设置成true.Tomcat就能自动监测到某个文件发生了改变,然后重新装载。由于对这个有点兴趣,所有也试着写了一个简单的实现,但对于文件夹下的多个文件监测,除了把每个文件都加入监测器中外,没有更好的思路和方法。大家可以讨论一下:
除件有我测试的整个eclipse工程文件,有兴趣的童鞋们可以看一下.
FileMonitor类的代码如下所示:
public class FileMonitor {
private static final FileMonitor instance = new FileMonitor();
private Timer timer;
private Map<String, FileMonitorTask> timerEntries;
private FileMonitor() {
this.timerEntries = new HashMap<String, FileMonitorTask>();
this.timer = new Timer();
}
public static FileMonitor getInstance() {
return instance;
}
/**
* 对某个文件实行监听
*
* @param listener
* The file listener
* @param filename
* The filename to watch
* @param period
* The watch interval.
*/
public void addFileChangeListener(FileChangeListener listener,
String filename, long period) {
this.removeFileChangeListener(filename);
FileMonitorTask task = new FileMonitorTask(listener, filename);
this.timerEntries.put(filename, task);
this.timer.schedule(task, period, period);
}
/**
* 停止对某个文件的监听
*
* @param listener
* The file listener
* @param filename
* The filename to keep watch
*/
public void removeFileChangeListener(String filename) {
FileMonitorTask task = (FileMonitorTask) this.timerEntries
.remove(filename);
if (task != null) {
task.cancel();
}
}
private static class FileMonitorTask extends TimerTask {
private FileChangeListener listener;
private String filename;
private File monitoredFile;
private long lastModified;
public FileMonitorTask(FileChangeListener listener, String filename) {
this.listener = listener;
this.filename = filename;
this.monitoredFile = new File(filename);
if (!this.monitoredFile.exists()) {
return;
}
this.lastModified = this.monitoredFile.lastModified();
}
public void run() {
long latestChange = this.monitoredFile.lastModified();
if (this.lastModified != latestChange) {
this.lastModified = latestChange;
//对发生改变的文件调用处理方法
this.listener.fileChanged(this.filename);
}
}
}
}
当监听到文件发生改变时处理的类如下所示:
public class ClassFileChangeListener implements FileChangeListener {
/*
* 当被监听的文件发生改变时,调用此方法
* */
public void fileChanged(String filename) {
System.out
.println("File " + filename + " modified ,it must reload !");
}
}
当web容器启动时,将要监听的文件加入到文件监听器类中,servet类如下所示:
public class InitServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
super.init(config);
long period = Long.parseLong(config.getInitParameter("period"));
String filename = config.getInitParameter("filename");
if(period > 0 && filename != null && !filename.isEmpty()){
//String realPath = config.getServletContext().getRealPath("");
//String filename = realPath + "\\WEB-INF\\classes\\jdbc.propertis";
FileMonitor.getInstance().addFileChangeListener(new ClassFileChangeListener(), filename, period);
}
}
/**
* @see HttpServlet#HttpServlet()
*/
public InitServlet() {
super();
// TODO Auto-generated constructor stub
}
}
web.xml中的配置如下所示:
<servlet> <description></description> <display-name>InitServlet</display-name> <servlet-name>InitServlet</servlet-name> <servlet-class>servlet.InitServlet</servlet-class> <init-param> <!-- the period of watching file --> <param-name>period</param-name> <!-- milliseconds --> <param-value>1000</param-value> </init-param> <init-param> <param-name>filename</param-name> <param-value>D:/aa.txt</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet>
由于使用eclipse开发时,eclipse中的tomcat,将文件部署在了:D:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp3\wtpwebapps
下面,如我的这个工程中的jdbc.properties文件部署成了D:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp3\wtpwebapps\MyTest\WEB-INF\classes\jdbc.propertis,
此时使用此路径创建的File不存在,所以为了方便测试,我将要监听的文件路径作为InitServlet的一个初始化参数了。
除件是整个工程的文件,直接导入eclipse中即可使用。