博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring @Async
阅读量:6452 次
发布时间:2019-06-23

本文共 7698 字,大约阅读时间需要 25 分钟。

  hot3.png

spring 的 @Async注解,通过AsyncExecutionInterceptor实现。

/* * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.springframework.aop.interceptor;import java.lang.reflect.Method;import java.util.concurrent.Callable;import java.util.concurrent.Executor;import java.util.concurrent.Future;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;import org.springframework.aop.support.AopUtils;import org.springframework.core.BridgeMethodResolver;import org.springframework.core.Ordered;import org.springframework.core.task.AsyncTaskExecutor;import org.springframework.util.ClassUtils;import org.springframework.util.ReflectionUtils;/** * AOP Alliance {@code MethodInterceptor} that processes method invocations * asynchronously, using a given {@link org.springframework.core.task.AsyncTaskExecutor}. * Typically used with the {@link org.springframework.scheduling.annotation.Async} annotation. * * 

In terms of target method signatures, any parameter types are supported. * However, the return type is constrained to either {@code void} or * {@code java.util.concurrent.Future}. In the latter case, the Future handle * returned from the proxy will be an actual asynchronous Future that can be used * to track the result of the asynchronous method execution. However, since the * target method needs to implement the same signature, it will have to return * a temporary Future handle that just passes the return value through * (like Spring's {@link org.springframework.scheduling.annotation.AsyncResult} * or EJB 3.1's {@code javax.ejb.AsyncResult}). * * 

As of Spring 3.1.2 the {@code AnnotationAsyncExecutionInterceptor} subclass is * preferred for use due to its support for executor qualification in conjunction with * Spring's {@code @Async} annotation. * * @author Juergen Hoeller * @author Chris Beams * @since 3.0 * @see org.springframework.scheduling.annotation.Async * @see org.springframework.scheduling.annotation.AsyncAnnotationAdvisor * @see org.springframework.scheduling.annotation.AnnotationAsyncExecutionInterceptor */public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport  implements MethodInterceptor, Ordered { /**  * Create a new {@code AsyncExecutionInterceptor}.  * @param executor the {@link Executor} (typically a Spring {@link AsyncTaskExecutor}  * or {@link java.util.concurrent.ExecutorService}) to delegate to.  */ public AsyncExecutionInterceptor(Executor executor) {  super(executor); } /**  * Intercept the given method invocation, submit the actual calling of the method to  * the correct task executor and return immediately to the caller.  * @param invocation the method to intercept and make asynchronous  * @return {@link Future} if the original method returns {@code Future}; {@code null}  * otherwise.  */ public Object invoke(final MethodInvocation invocation) throws Throwable {  Class

 targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);  Method specificMethod = ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);  specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);  AsyncTaskExecutor executor = determineAsyncExecutor(specificMethod);  if (executor == null) {   throw new IllegalStateException(     "No executor specified and no default executor set on AsyncExecutionInterceptor either");  }  Future
 result = executor.submit(    new Callable() {     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;     }    });  if (Future.class.isAssignableFrom(invocation.getMethod().getReturnType())) {   return result;  }  else {   return null;  } } /**  * This implementation is a no-op for compatibility in Spring 3.1.2.  * Subclasses may override to provide support for extracting qualifier information,  * e.g. via an annotation on the given method.  * @return always {@code null}  * @see #determineAsyncExecutor(Method)  * @since 3.1.2  */ @Override protected String getExecutorQualifier(Method method) {  return null; } public int getOrder() {  return Ordered.HIGHEST_PRECEDENCE; }}

 

   配置task

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

 

  在web.xml配置

 
    
    
        
org.springframework.web.context.ContextLoaderListener
    
    
        
contextConfigLocation
        
classpath*:applicationContext-mybatis.xml,classpath*:applicationContext-task.xml
    
    
    
        
dispatcherServlet
        
org.springframework.web.servlet.DispatcherServlet
        
            
contextConfigLocation
            
classpath*:applicationContext-web.xml
        
        
1
        
true
    
    
        
dispatcherServlet
        
/
    

   如果出现async失效,则应该注意下task是否放到子context里面去了,应该放到root context声明。

 

1、controller

 @RequestMapping("/async")    @ResponseBody    public String testAsync(){        for(int i=0;i<10;i++){            asyncService.testAsync();//            asyncService.rightAsync();//            asyncService.poolAsync();        }        logger.info("main end");        return "ok";    }

2、service

package com.yami.service;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.annotation.Async;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import org.springframework.stereotype.Service;import javax.annotation.Resource;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * async示例 * @author scipio * @created 2014-03-08 */@Servicepublic class AsyncService {    private static Logger logger = LoggerFactory.getLogger(AsyncService.class);    @Resource    private ProductService productService;    private ExecutorService executor = Executors.newFixedThreadPool(5);    public void poolAsync(){       for(int i=0;i<10;i++){           executor.submit(new Runnable() {               @Override               public void run() {                   oneExecute();               }           });       }    }    private int oneExecute(){        logger.info("I Will be formatting html mail and sending it");        try {            Thread.sleep(5*1000);        } catch (InterruptedException e) {            e.printStackTrace();        }        productService.getProduct("abcd");        logger.info("Asynchronous method call of send email — Complete");        return 1;    }    @Async    public void testAsync(){        oneExecute();    }}

转载于:https://my.oschina.net/scipio/blog/206425

你可能感兴趣的文章
ConcurrentHashMap 详解二
查看>>
互联网数据化运营基础应用之信息质量模型
查看>>
安卓面试中高级安卓开发面试高频题之——equals()和hashcode()关系,区别...
查看>>
关于Web事务响应时间的细分以及深入分析
查看>>
PostgreSQL 10.1 手册_部分 II. SQL 语言_第 5 章 数据定义_5.2. 默认值
查看>>
Android 图解创建外部 lib 库及自定义 View
查看>>
地平线将获10亿美元B轮融资,估值40亿美元
查看>>
esp8266-01 替换4M Flash(搬运)
查看>>
Android IPC机制(2)-AIDL
查看>>
2018年CCF优秀学生分会结果出炉——将持续致力提升会员本地化服务
查看>>
Confluence 6 管理全站权限和用户组
查看>>
浏览器全屏非全屏切换
查看>>
02 pandas Series_创建、属性
查看>>
【实践】视频播放成功率下降很多?可能是你密钥管理的方式不对!
查看>>
策略模式
查看>>
分布式系统理论基础8:zookeeper分布式协调服务
查看>>
Java并发指南8:AQS中的公平锁与非公平锁,Condtion
查看>>
AI学习笔记——卷积神经网络(CNN)
查看>>
如何将本地的demo上传到自己的github
查看>>
nginx 负载均衡配置
查看>>