在我的Spring boot
应用程序Web容器中禁用。因此,当我开始应用程序时,它可以正常运行并关闭自己。我在服务中使用@Async
方法并从jUnit测试运行它。它在并行线程中应该工作。但应用程序关闭的问题。当jUnit测试完成Spring Boot
关闭应用程序但@Async
线程仍然并行运行时,我得到了一个异常。要使@Async
线程能够在关闭之前完成,我将 waitForTasksToCompleteOnShutdown 属性设置为 true 。之后 Spring Boot关闭但并行线程没有完成,甚至没有异常捕获。为什么?在并行线程完成之前如何强制Spring Boot
不关闭?
此处app输出waitForTasksToCompleteOnShutdown = false
Test thread closed
Thread sleep intrerrupted - async method test url string 2
Thread sleep intrerrupted - async method test url string 4
Thread sleep intrerrupted - async method test url string 0
Thread sleep intrerrupted - async method test url string 3
Thread sleep intrerrupted - async method test url string 1
此处app输出waitForTasksToCompleteOnShutdown = true
。如您所见,@Async
方法没有输出任何内容,因此@Async
线程未完成其工作:
Test thread closed
更新 作为提出的解决方案,我试图在测试中注入ThreadPoolTaskExecutor bean,但结果不会改变。与以前相同的输出。这里是JUnit测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = CLApplication.class)
@TestPropertySource(locations="classpath:test.properties")
public class CatalogPageServiceImplTest {
@Autowired
CatalogPageService catalogPageService;
@Resource(name="locationPageExecutor")
ThreadPoolTaskExecutor locationPageExecutor;
@Test
public void processPageTest(){
for (int i=0; i<5; i++){
catalogPageService.processPage(
new CatalogPage("test url string "+Integer.toString(i)));
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
System.out.println("Test thread sleep intrerrupted");
}
locationPageExecutor.shutdown();
System.out.println("Test thread closed");
}
}
SpringBoot主类:
@SpringBootApplication
@EnableAsync
public class CLApplication {
private static final Logger log = LoggerFactory.getLogger(CLApplication.class);
@Bean
public TaskExecutor locationPageExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(20);
executor.setWaitForTasksToCompleteOnShutdown(true);
return executor;
}
public static void main(String[] args) {
log.info("Application main method call");
try{
SpringApplication.run(CLApplication.class, args);
}catch(Throwable t){
log.error("Unexpected error: ",t);
}
log.info("Application main method exit");
}
}
服务:
@Service
public class CatalogPageServiceImpl implements CatalogPageService {
@Override
@Async("locationPageExecutor")
public void processPage(CatalogPage catalogPage) {
try {
Thread.sleep(500);
System.out.println("print from Async method "+catalogPage.getUrl());
} catch (InterruptedException e) {
System.out.println("Thread sleep intrerrupted - async method "+catalogPage.getUrl());
}
}
}
测试
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = CLApplication.class)
@TestPropertySource(locations="classpath:test.properties")
public class CatalogPageServiceImplTest {
@Autowired
CatalogPageService catalogPageService;
@Test
public void processPageTest(){
for (int i=0; i<5; i++){
catalogPageService.processPage(
new CatalogPage("test url string "+Integer.toString(i)));
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
System.out.println("Test thread sleep intrerrupted");
}
System.out.println("Test thread closed");
}
}