【发布时间】:2011-09-07 01:57:38
【问题描述】:
我有一个在 tomcat6 中运行的应用程序,它在启动时读取一个资源文件(一个简单的文本文件,没有 xml)来配置/实例化一些类。现在我希望能够修改该文件并将更改反映在应用程序中,而无需重新启动服务器。有没有办法做到这一点?
基本上,如果我可以定义一个侦听器并将其附加到该资源,这就是我所需要的。
【问题讨论】:
我有一个在 tomcat6 中运行的应用程序,它在启动时读取一个资源文件(一个简单的文本文件,没有 xml)来配置/实例化一些类。现在我希望能够修改该文件并将更改反映在应用程序中,而无需重新启动服务器。有没有办法做到这一点?
基本上,如果我可以定义一个侦听器并将其附加到该资源,这就是我所需要的。
【问题讨论】:
【讨论】:
您可以通过编程方式触发一项服务,该服务将使用新文件刷新这些类
【讨论】:
不确定是否有内置的资源侦听器,但是启动一个新线程来监视文件系统中的文件(例如,在上次更新的日期/时间)并在更改时刷新类会相当简单.
【讨论】:
在 web 应用程序中启动一个计时器,获取资源文件如下:
在 ServletContextListener.contextInitialized() 中,
package com.servlets;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class WatcherListener
implements ServletContextListener
{
public void contextInitialized(ServletContextEvent event)
{
ServletContext servletContext = event.getServletContext();
Timer timer = new Timer("ResourceListener");
timer.schedule(new MyWatcherTask(servletContext), 15);
}
public void contextDestroyed(ServletContextEvent event)
{
}
private class MyWatcherTask extends TimerTask
{
private final ServletContext servletContext;
private long lastModifiedTime = -1;
public MyWatcherTask(ServletContext servletContext)
{
this.servletContext = servletContext;
}
public void run()
{
URL resource = null;
try {
resource = servletContext.getResource("resouceFileName");
File resourceFile = new File(resource.toString());
long current = resourceFile.lastModified();
if (current > lastModifiedTime) {
reloadReources();
}
lastModifiedTime = current;
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
}
以上代码只是一个模板
【讨论】:
ScheduledExecutorService 而不是TimerTask。另见stackoverflow.com/questions/409932/… 和stackoverflow.com/questions/5798688/reload-servlet-once-a-month。或者,当您使用支持 EJB 的容器的 Java EE 6 时,更喜欢 @Singleton 和 @Schedule。另见stackoverflow.com/questions/5357033/…。