我正在使用Spring的@Sync注释,我遇到了一些古怪的行为。我已经整理了一个非常简单的测试用例,它只是不起作用(我的异步方法没有被调用)。以某种方式调整测试用例确实会导致调用该方法,但很难理解为什么。无论如何,这里是细节。我正在使用基于注释的配置和自动装配。
我已经使用Spring 3.1.1和3.2.3进行了测试。
a)Spring上下文文件:
<context:annotation-config />
<context:component-scan base-package="sample" />
<task:annotation-driven />
b)包含异步方法的类:
package sample;
@Component
public class SomeServiceImpl {
@Async
public void asynchMethod(String in) {
logger.debug("Starting asynchMethod");
logger.debug("Ending asynchMethod");
}
public void doNothing() {
}
}
c)单元测试(在TestSomeService类中):
@Test
public void testAsynch() throws InterruptedException {
logger.debug("Starting testAsynch");
service.asynchMethod("hello asynch");
logger.debug("Ending testAsynch");
}
以下是单元测试结果:
[DEBUG] [2013-06-13 09:18:10,350] [sample.TestSomeService] - Starting testAsynch
[DEBUG] [2013-06-13 09:18:10,353] [sample.TestSomeService] - Ending testAsynch
异步方法没有输出 - 所以问题#1。这个例子很简单,我不明白它为什么不起作用。
NEXT - 如果我通过添加对同步方法“doNothing()”的调用来修改测试:
@Test
public void testAsynch() throws InterruptedException {
logger.debug("Starting testAsynch");
service.doNothing();
service.asynchMethod("hello asynch");
logger.debug("Ending testAsynch");
}
执行异步方法:
[DEBUG] [2013-06-13 09:20:59,493] [sample.TestSomeService] - Starting testAsynch
[DEBUG] [2013-06-13 09:20:59,515] [sample.TestSomeService] - Ending testAsynch
[DEBUG] [2013-06-13 09:20:59,515] [sample.SomeServiceImpl] - Starting asynchMethod
[DEBUG] [2013-06-13 09:20:59,515] [sample.SomeServiceImpl] - Ending asynchMethod
我无法理解为什么第一次调用同步方法会使异步方法调用工作。
NEXT - 更令人费解的是:如果我在调用异步方法后让我的单元测试进入休眠状态一秒钟 - 异步方法会执行。
@Test
public void testAsynch() throws InterruptedException {
logger.debug("Starting testAsynch");
service.asynchMethod("hello asynch");
Thread.sleep(1000);
logger.debug("Ending testAsynch");
}
[DEBUG] [2013-06-13 09:22:21,187] [sample.TestSomeService] - Starting testAsynch
[DEBUG] [2013-06-13 09:22:21,209] [sample.SomeServiceImpl] - Starting asynchMethod
[DEBUG] [2013-06-13 09:22:21,209] [sample.SomeServiceImpl] - Ending asynchMethod
[DEBUG] [2013-06-13 09:22:22,190] [sample.TestSomeService] - Ending testAsynch
我很困惑为什么简单的情况不起作用,以及为什么其他两个修改确实有效。谁能看到我错过的东西?
答案 0 :(得分:2)
在执行异步调用的线程有机会运行之前,Junit运行结束(JVM暂停),因此睡眠会有所帮助。