如何使用@Async批注在Spring 4.x中启动长时间运行的进程

时间:2018-04-10 11:13:30

标签: spring spring-annotations

我正在开发一个我的第一个Spring(4.x)服务,它使用WatchService.take()来等待文件系统的更改。因此,这些服务的运行时间可能很长。所以我添加了包含WatchService.take()和@Async

的方法
@Service
public class ReceiveService() {

   @Async
    protected void startService() {
      LOG.info("Started service ReceiveService");
      ...
      WatchKey watchKey  = WatchService.take()
      ...
   }
}

该服务是从具有@EnableAsync注释的另一个组件的PostConstruct中启动的。

@Component
@EnableAsync
public class receiveServiceController{

    @Autowired
    private ReceiveService receiveService;


    @PostConstruct
    public void Init() {
        LOG.info("Starting service ReceiveService");
        ReceiveService.startService();
    }
}

我已经浏览了一些博客和文章,但找不到有什么问题。在部署应用程序时,会记录两个日志条目,但似乎应用程序上下文的进一步加载会停止。我期望的是,ReceiveService.startService()上的调用不是异步调用的,因此我犯了一些错误。

==更新1 ==

我创建了一个@Configuration类作为

public class ReceiveServiceConfiguration {

    @Bean(name = "ReceiveServiceExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(1);
        executor.setQueueCapacity(1);
        executor.setThreadNamePrefix("ReceiveService-");
        executor.initialize();
        return executor;
    }
}

从receiveServiceController中删除了@EnableAsync注释。并使用@Async替换了startService方法的@Async注释(" ReceiveServiceExecutor") 在部署它时,初始化似乎在再次调用ReceiveService.startService()方法时挂起。

1 个答案:

答案 0 :(得分:0)

有两件事是错的;

receiveServiceController中第一次自动装配ReceiveService应该自动装配接口而不是实现。

其次@Async虽然未在Spring documentation中明确记录,但只能应用于Public方法。因此protected void startService()必须更改为public void startService()