我正在使用带有Apache Tomcat 8.5的Spring Framework 4.2开发Web应用程序。当我修改目录中的文件时,我需要调用bean对象中的方法来重新加载信息。 我使用Apache Commons IO来查看目录,但是当我取消部署应用程序时,扫描目录的线程仍然存在。
这是观看更改的代码
final File directory = new File(groupsDirectory);
FileAlterationObserver fao = new FileAlterationObserver(directory);
fao.addListener(new FileAlterationListenerImpl());
final FileAlterationMonitor monitor = new FileAlterationMonitor(pollingInterval);
monitor.addObserver(fao);
monitor.start();
这是我取消部署web应用程序时Tomcat向我显示的消息:
22-May-2016 19:13:14.377警告[http-nio-8084-exec-12] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web应用程序[Argo]似乎已经启动了一个名为[ Thread-12]但未能阻止它。这很可能造成内存泄漏。堆栈跟踪线程: java.lang.Thread.sleep(Native方法) org.apache.commons.io.monitor.FileAlterationMonitor.run(FileAlterationMonitor.java:188) java.lang.Thread.run(Thread.java:745)
答案 0 :(得分:0)
你可以做的是实现一个ServletContextListener,如本文所述:Call method on undeploy from a Java web-application
然后,您应该可以使用contextDestroyed()
的{{1}}方法停止监视器。
我建议让一个Factory对象保留在 static 监视器实例上,然后你可以调用Factory,而不是让ServletContextListener
直接处理监视器。
工厂将坚持使用类加载器的生命周期(例如,启动webapp的持续时间)
答案 1 :(得分:0)
我只是使用注释@PreDestroy在应用程序停止之前停止监视器。
@Component
public class GroupsMonitor {
private final FileAlterationMonitor monitor;
@Autowired
public GroupsMonitor(@Value("${groups.directory}") String groupsDirectory,
@Value("${groups.intervalMonitor}") long pollingInterval) throws Exception {
final File directory = new File(groupsDirectory);
FileAlterationObserver fao = new FileAlterationObserver(directory);
fao.addListener(new FileAlterationListenerImpl());
monitor = new FileAlterationMonitor(pollingInterval);
monitor.addObserver(fao);
monitor.start();
}
@PreDestroy
public void stop() {
try {
monitor.stop();
} catch (Exception ex) {
Logger.getLogger(StopWatcher.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
答案 2 :(得分:0)
旧回答但FileAlterationMonitor
仍然存在问题。
即使您致电FileAlterationMonitor#stop()
,显示器也不会停止,直到pollingInterval
延迟结束。
请参阅:https://github.com/apache/commons-io/pull/58
解决问题的另一种方法是为pollingInterval
设置一个小值。