Java 带弹簧的手表

Java 带弹簧的手表,java,spring,watchservice,Java,Spring,Watchservice,我试图用spring执行“WatchService”,但这看起来是不可能的,因为当我试图在应用程序上下文时运行此服务,但当控制到达时,spring上下文的加载将停止 key=watcher.take(); 由于这个原因,应用程序上下文的加载没有发生 下面是完整的代码 @组件 公共类DirectoryWatchDemo{ @施工后 公共静态无效测试(){ 试一试{ WatchService watcher=FileSystems.getDefault().newWatchService(); P

我试图用spring执行“WatchService”,但这看起来是不可能的,因为当我试图在应用程序上下文时运行此服务,但当控制到达时,spring上下文的加载将停止

key=watcher.take();
由于这个原因,应用程序上下文的加载没有发生

下面是完整的代码

@组件
公共类DirectoryWatchDemo{
@施工后
公共静态无效测试(){
试一试{
WatchService watcher=FileSystems.getDefault().newWatchService();
Path dir=Path.get(“C:/test”);
目录寄存器(观察者、条目和创建);
System.out.println(“为dir注册的监视服务:+dir.getFileName());
while(true){
监视键;
试一试{
key=watcher.take();
}捕获(中断异常例外){
返回;
}
for(WatchEvent事件:key.pollEvents()){
WatchEvent.Kind-Kind=event.Kind();
@抑制警告(“未选中”)
WatchEvent ev=(WatchEvent)事件;
路径文件名=ev.context();
System.out.println(kind.name()+“:”+文件名);
如果(种类==条目\u修改&&
fileName.toString().equals(“DirectoryWatchDemo.java”)){
System.out.println(“我的源文件已更改!!!”;
}
}
布尔有效值=key.reset();
如果(!有效){
打破
}
}
}捕获(IOEX异常){
系统错误打印项次(ex);
}
}
}
我这样做是因为我不想手动执行“WatchService”。

等待下一个监视键:“检索并删除下一个监视键,如果没有,则等待。”

-这是一个Java注释,而不是Spring注释--用于一个需要在依赖项注入完成后执行的方法,以执行任何初始化。必须在类投入使用之前调用此方法。”根据此文档,在bean投入使用之前,似乎必须返回后构造(“必须在类投入服务之前调用”)

但是您的
PostConstruct
方法不会返回;因此
PostConstruct
不是您需要的

您可以考虑实现Spring接口,它提供回调方法<代码>后置属性SET/COD>。它应该允许您启动这种类型的服务方法。< /P>


否则,您可以查看Apache VFS2虚拟文件系统,它包括一个文件夹监视程序。这就是我的项目所使用的;在系统启动时启动监视程序非常容易;而且,它监视文件删除、更新和创建事件(与Camel文件监视程序不同).

这是因为您有一个无止境的循环,因此
@PostConstruct
的方法调用永远不会返回

(对我来说很奇怪,
@PostConstruct
可以使用静态方法,但这可能有效)

因此,解决方案是为您的观察者启动一个新线程。您可以通过不同的方式执行此操作:

  • 只要开始一个新的线程
  • @Async
    添加到该方法中(我不知道这是否适用于
    @PostConstruct
    方法)(主要缺点是,这在初始化完整的应用程序上下文之前启动)
  • 滥用
    @Scheduler
    注释:
    @Scheduled(fixedDelay=Long.MAX_值)
    -(与
    @PostConstruct
    +
    @Async
    相比的优点是:它确实可以工作,并且在初始化完整上下文后立即启动)

谢谢回答:“我使用的是MealPoice,它是为MeGoad回答的。”Spring是其他解决方案是HaskS。你也可以考虑将观察者看做是一个bean,因为它是一个长的活体对象,应该可能是由Spring产生的。注意<代码> @ AycNc< /Calp>和< Case> @ PrimeStudio< /Cord>不能结合使用。()。并且
@Scheduled
不允许像异步调用方法一样传递参数。对于我的用例,我最终在
@PostConstruct
方法中使用
执行器。newSingleThreadExecutor()。。。