`
jinnianshilongnian
  • 浏览: 21435365 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2405208
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2997857
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5631575
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257590
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1593252
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:248993
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5847698
Group-logo
跟我学Nginx+Lua开...
浏览量:698206
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:780544
社区版块
存档分类
最新评论

如何测试@Async异步任务

阅读更多

spring3支持@Async注解的异步任务,之前大家都是通过使用如线程池来完成,spring3也是使用这种方式,但更简单。

 

其具体实现在:org.springframework.aop.interceptor.AsyncExecutionInterceptor,是一个方法拦截器,其invoke方法的部分代码如下: 

Future<?> result = determineAsyncExecutor(specificMethod).submit(
                new Callable<Object>() {
                    public Object call() throws Exception {
                        try {
                            
                            Object result = invocation.proceed();
                            if (result instanceof Future) {
                                return ((Future<?>) result).get();
                            }
                        }
                        catch (Throwable ex) {
                            ReflectionUtils.rethrowException(ex);
                        }
                        return null;
                    }
                });

即把当前任务的调用提交给线程池,很简单。

 

 

1、测试无事务的异步任务

这个相对来说比较简单:

1.1、设置任务的返回值为Future: 

public Future sendSystemMessage(Long[] receiverIds, Message message);

 

1.2、调用future.get();等待任务结束。 

        Future future = messageApi.sendSystemMessage(userIds, message);
        future.get();

 

 这个很简单。

 

2、测试带事务的异步任务

因为是带事务的,所以异步任务肯定要启动一个线程来执行任务,所以无法在主线程回滚,造成数据会commit到数据库,这在集成测试时肯定是不行的;解决方案是移除异步任务:

 

2.1、使用spring profile,在测试环境下不执行<task:annotation-driven>即可。

 

2.2、使用我提供的工具类,在测试时移除异步支持即可: 

        //移除异步支持
        if(AopProxyUtils.isAsync(messageApi)) {
            AopProxyUtils.removeAsync(messageApi);
        }

 

测试类可以参考MessageApiServiceIT.java 

工具类下载 AopProxyUtils.java

 

3、包级别测试 

@Async
public void sendSystemMessage() {
      sendSystemMessageInner();
}

void sendSystemMessageInner() {
      //测试时测试这个方法即可
}

 这样测试时测试这个包级别的sendSystemMessageInner方法即可

 

 

 其实更好的做法是spring内部提供支持,支持这样异步调用的测试。

2
3
分享到:
评论
2 楼 jinnianshilongnian 2013-07-09  
7454103 写道
引用

1.//移除异步支持  
2.if(AopProxyUtils.isAsync(messageApi)) {  
3.    AopProxyUtils.removeAsync(messageApi);  
4.} 



疑问:这个异步任务是否可能在主线程执行到需要回滚的时候 就已经开始执行了呢(或者执行完成了呢)

在执行异步任务之前执行这句话 就没问题了
1 楼 7454103 2013-07-09  
引用

1.//移除异步支持  
2.if(AopProxyUtils.isAsync(messageApi)) {  
3.    AopProxyUtils.removeAsync(messageApi);  
4.} 



疑问:这个异步任务是否可能在主线程执行到需要回滚的时候 就已经开始执行了呢(或者执行完成了呢)

相关推荐

Global site tag (gtag.js) - Google Analytics