Spring 启动时不能按顺序运行 几个方法

Can not run few methods sequentially when Spring Boot starts

当应用程序启动时,我必须运行一些方法,如下所示:

@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

总是跳过第二个!

如果更改调用顺序 - 只有第二个会被执行。

一开始找不到启动两者的解决方案 - 尝试了 @PostConstructApplicationRunner@EventListener(ApplicationReadyEvent.class)...

看起来他们以某种方式互相阻挡。尽管 都是 void 类型 .

监控启动实施:

@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 来启用异步 然后用 @Async

注释 launchMonitoring()

不确定 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;
     }

    ...
 }