Spring Batch:从一个带有新线程的Spring MVC控制器中启动一个作业

我有一个Spring-Batch作业,我从Spring MVC控制器启动。 控制器从用户获取上传的文件,该作业应该处理该文件:

@RequestMapping(value = "/upload") public ModelAndView uploadInventory(UploadFile uploadFile, BindingResult bindingResult) { // code for saving the uploaded file to disk goes here... // now I want to launch the job of reading the file line by line and saving it to the database, // but I want to launch this job in a new thread, not in the HTTP request thread, // since I so not want the user to wait until the job ends. jobLauncher.run( jobRegistry.getJob(JOB_NAME), new JobParametersBuilder().addString("targetDirectory", folderPath).addString("targetFile", fileName).toJobParameters() ); return mav; } 

我尝试过以下XML配置:

            

…但似乎multithreading仅在作业边界内发生。 即,控制器线程等待直到作业结束,并且作业执行由多个线程处理(这是好的但不是我想要的主要内容)。 我想要的主要是作业将在一个单独的线程(或线程)上启动,而控制器线程将继续执行而不等待作业线程结束。

有没有办法用Spring-batch实现这个目标?

官方文档描述了您的确切问题以及4.5.2中的解决方案。 从Web容器中运行作业 :

[…]控制器使用已配置为异步启动JobLauncher启动作业,该作业立即返回JobExecution 。 作业可能仍在运行,但是,这种非阻塞行为允许控制器立即返回 ,这在处理HttpRequest时是必需的。

Spring Batch http://sofzh.miximages.com/java/launch-from-request.png

所以你非常接近尝试使用TaskExecutor ,但是它需要传递给JobLauncher

     

免责声明:我从未使用过Spring Batch …

jobLauncher.run()方法可以在新的Thread调用,如下所示:

 @RequestMapping(value = "/upload") public ModelAndView uploadInventory(UploadFile uploadFile, BindingResult bindingResult) { [...] final SomeObject jobLauncher = [...] Thread thread = new Thread(){ @Override public void run(){ jobLauncher.run([...]); } }; thread.start(); return mav; } 

thread.start()行将生成一个新线程,然后继续执行它下面的代码。

请注意,如果jobLauncher是局部变量,则必须将其声明为final ,以便在匿名Thread类中使用它。

如果您不需要向客户端显示处理错误,则可以在单独的线程中启动spring批处理作业。