问题描述
应用程序启动时,我必须运行一些方法,如下所示:
@SpringBootApplication
public class Application implements CommandLineRunner {
private final MonitoringService monitoringService;
private final QrReaderServer qrReaderServer;
@Override
public void run(String... args) {
monitoringService.launchMonitoring();
qrReaderServer.launchServer();
}
但是,只有第一个被执行!然后启动应用程序:
... Started Application in 5.21 seconds (JVM running for 6.336)
... START_MONITORING for folder: D:\results
第二个总是被跳过!
如果更改呼叫顺序-将仅执行第二个呼叫。
找不到一开始就启动的任何解决方案-尝试过@postconstruct
,ApplicationRunner
,@EventListener(ApplicationReadyEvent.class)
...
看起来他们以某种方式互相阻碍。尽管 都具有空类型 。
监视启动实施:
@Override
public void launchMonitoring() {
log.info("START_MONITORING for folder: {}",monitoringProperties.getFolder());
try {
WatchKey key;
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (kind == ENTRY_CREATE) {
log.info("FILE_CREATED: {}",event.context());
// some delay for fully file upload
Thread.sleep(monitoringProperties.getFrequency());
String fullFileName = getFileName(event);
String fileName = FilenameUtils.removeExtension(fullFileName);
processResource(fullFileName,fileName);
}
}
key.reset();
}
} catch (InterruptedException e) {
log.error("interrupted exception for monitoring service",e);
} catch (IOException e) {
log.error("io exception while processing file",e);
}
}
QR Reader启动(使用Netty配置启动TCP服务器):
@Override
public void launchServer() {
try {
ChannelFuture serverChannelFuture = serverBootstrap.bind(hostAddress).sync();
log.info("Server is STARTED : port {}",hostAddress.getPort());
serverChannel = serverChannelFuture.channel().closeFuture().sync().channel();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
shutdownQuietly();
}
}
如何解决此问题?
解决方法
异步启动launchMonitoring()
。
最简单的方法是在应用程序上添加@EnableAsync
以启用异步
然后用launchMonitoring()
注释@Async
不确定launchServer()
是否也应该异步启动。
编辑:完成的答案
No task executor bean found for async processing: no bean of type TaskExecutor and no bean named 'taskExecutor' either
默认情况下,Spring将创建一个SimpleAsyncTaskExecutor
,但是您可以提供taskExecutor
示例:
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.set... // your custom configs
executor.initialize();
return executor;
}
...
}