amk*_*mkz 7 java spring-integration spring-boot
我不会在Spring中编写Spring Boot Application,它将监视Windows中的目录,当我更改子文件夹或添加新的文件夹或删除现有的文件夹时,我想获取有关该文件夹的信息。
我怎样才能做到这一点?我已经读过这篇文章:http : //docs.spring.io/spring-integration/reference/html/files.html 和google中“ spring file watcher”下的每个结果,但是我找不到解决方案...
您是否有类似这样的好文章或示例?我不想这样:
@SpringBootApplication
@EnableIntegration
public class SpringApp{
public static void main(String[] args) {
SpringApplication.run(SpringApp.class, args);
}
@Bean
public WatchService watcherService() {
...//define WatchService here
}
}
Run Code Online (Sandbox Code Playgroud)
问候
Hit*_*eeb 12
spring-boot-devtools 已 FileSystemWatcher
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
文件观察者配置
@Configuration
public class FileWatcherConfig {
@Bean
public FileSystemWatcher fileSystemWatcher() {
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(true, Duration.ofMillis(5000L), Duration.ofMillis(3000L));
fileSystemWatcher.addSourceFolder(new File("/path/to/folder"));
fileSystemWatcher.addListener(new MyFileChangeListener());
fileSystemWatcher.start();
System.out.println("started fileSystemWatcher");
return fileSystemWatcher;
}
@PreDestroy
public void onDestroy() throws Exception {
fileSystemWatcher().stop();
}
}
Run Code Online (Sandbox Code Playgroud)
我的文件更改监听器
@Component
public class MyFileChangeListener implements FileChangeListener {
@Override
public void onChange(Set<ChangedFiles> changeSet) {
for(ChangedFiles cfiles : changeSet) {
for(ChangedFile cfile: cfiles.getFiles()) {
if( /* (cfile.getType().equals(Type.MODIFY)
|| cfile.getType().equals(Type.ADD)
|| cfile.getType().equals(Type.DELETE) ) && */ !isLocked(cfile.getFile().toPath())) {
System.out.println("Operation: " + cfile.getType()
+ " On file: "+ cfile.getFile().getName() + " is done");
}
}
}
}
private boolean isLocked(Path path) {
try (FileChannel ch = FileChannel.open(path, StandardOpenOption.WRITE); FileLock lock = ch.tryLock()) {
return lock == null;
} catch (IOException e) {
return true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
从 Java 7 开始,有WatchService - 这将是最好的解决方案。
Spring 配置可能如下所示:
@Slf4j
@Configuration
public class MonitoringConfig {
@Value("${monitoring-folder}")
private String folderPath;
@Bean
public WatchService watchService() {
log.debug("MONITORING_FOLDER: {}", folderPath);
WatchService watchService = null;
try {
watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get(folderPath);
if (!Files.isDirectory(path)) {
throw new RuntimeException("incorrect monitoring folder: " + path);
}
path.register(
watchService,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_CREATE
);
} catch (IOException e) {
log.error("exception for watch service creation:", e);
}
return watchService;
}
}
Run Code Online (Sandbox Code Playgroud)
和用于启动监控本身的 Bean:
@Slf4j
@Service
@AllArgsConstructor
public class MonitoringServiceImpl {
private final WatchService watchService;
@Async
@PostConstruct
public void launchMonitoring() {
log.info("START_MONITORING");
try {
WatchKey key;
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
log.debug("Event kind: {}; File affected: {}", event.kind(), event.context());
}
key.reset();
}
} catch (InterruptedException e) {
log.warn("interrupted exception for monitoring service");
}
}
@PreDestroy
public void stopMonitoring() {
log.info("STOP_MONITORING");
if (watchService != null) {
try {
watchService.close();
} catch (IOException e) {
log.error("exception while closing the monitoring service");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
此外,您必须@EnableAsync为您的应用程序类(它的配置)进行设置。
并从application.yml:
监控文件夹:C:\Users\nazar_art
使用 Spring Boot 进行测试2.3.1。
还用于异步池的配置:
@Slf4j
@EnableAsync
@Configuration
@AllArgsConstructor
@EnableConfigurationProperties(AsyncProperties.class)
public class AsyncConfiguration implements AsyncConfigurer {
private final AsyncProperties properties;
@Override
@Bean(name = "taskExecutor")
public Executor getAsyncExecutor() {
log.debug("Creating Async Task Executor");
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(properties.getCorePoolSize());
taskExecutor.setMaxPoolSize(properties.getMaxPoolSize());
taskExecutor.setQueueCapacity(properties.getQueueCapacity());
taskExecutor.setThreadNamePrefix(properties.getThreadName());
taskExecutor.initialize();
return taskExecutor;
}
@Bean
public TaskScheduler taskScheduler() {
return new ConcurrentTaskScheduler();
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new CustomAsyncExceptionHandler();
}
}
Run Code Online (Sandbox Code Playgroud)
自定义异步异常处理程序在哪里:
@Slf4j
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
log.error("Exception for Async execution: ", throwable);
log.error("Method name - {}", method.getName());
for (Object param : objects) {
log.error("Parameter value - {}", param);
}
}
}
Run Code Online (Sandbox Code Playgroud)
属性文件中的配置:
async-monitoring:
core-pool-size: 10
max-pool-size: 20
queue-capacity: 1024
thread-name: 'async-ex-'
Run Code Online (Sandbox Code Playgroud)
小智 5
您可以为此使用纯 Java,无需 spring https://docs.oracle.com/javase/tutorial/essential/io/notification.html
| 归档时间: |
|
| 查看次数: |
16218 次 |
| 最近记录: |