Spring开启方法异步执行

@EnableAsync

  1. @Target(ElementType.TYPE)

  2. @Retention(RetentionPolicy.RUNTIME)

  3. @Documented

  4. @Import(AsyncConfigurationSelector.class)

  5. public @interface EnableAsync {

  6.  

  7.    Class<? extends Annotation> annotation() default Annotation.class;

  8.  

  9.    boolean proxyTargetClass() default false;

  10.  

  11.    AdviceMode mode() default AdviceMode.PROXY;

  12.  

  13.    int order() default Ordered.LOWEST_PRECEDENCE;

  14.  

  15. }

@EnableAsync注解即开启Spring对方法异步执行的能力,需要和注解@Configuration配合使用。

  1. @Configuration

  2. @EnableAsync

  3. public class AppConfig {

  4.  

  5. }

也可以自定义线程池

  1. @Configuration

  2. @EnableAsync

  3. public class AppConfig implements AsyncConfigurer {

  4.  

  5.     @Override

  6.     public Executor getAsyncExecutor() {

  7.         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

  8.         executor.setCorePoolSize(7);

  9.         executor.setMaxPoolSize(42);

  10.         executor.setQueueCapacity(11);

  11.         executor.setThreadNamePrefix("MyExecutor-");

  12.         executor.initialize();

  13.         return executor;

  14.     }

  15.  

  16.     @Override

  17.     public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {

  18.         return MyAsyncUncaughtExceptionHandler();

  19.     }

  20. }

@Async

  1. @Target({ElementType.METHOD, ElementType.TYPE})

  2. @Retention(RetentionPolicy.RUNTIME)

  3. @Documented

  4. public @interface Async {

  5.  

  6.    String value() default "";

  7.  

  8. }

在要异步执行的方法上使用@Async注解,下面是一个没有返回值,一个带有返回值的异步调用的示例。

  1. @Component

  2. public class AsyncTask {

  3.  

  4.    @Async

  5.    public void task1() {

  6.        try {

  7.            Thread.sleep(3000);

  8.        } catch (InterruptedException e) {

  9.            e.printStackTrace();

  10.        }

  11.    }

  12.  

  13.    @Async

  14.    public Future<String> task2() {

  15.        try {

  16.            Thread.sleep(3000);

  17.        } catch (InterruptedException e) {

  18.            e.printStackTrace();

  19.        }

  20.        return new AsyncResult<String>("javastack");  

  21.    }

  22.  

  23. }

测试代码

  1. @RunWith(SpringRunner.class)

  2. @SpringBootTest

  3. public class AsyncTest {

  4.  

  5.    private final static Logger log = LoggerFactory.getLogger(AsyncTest.class);

  6.  

  7.    @Autowired

  8.    private AsyncTask asyncTask;

  9.  

  10.    @Test

  11.    public void testTask1(){

  12.        log.info("start");

  13.        asyncTask.task1();

  14.        log.info("finish");

  15.    }

  16.  

  17.    @Test

  18.    public void testTask2()  {

  19.        log.info("start");

  20.        Future<String> future = asyncTask.task2();

  21.        while (true) {

  22.            if (future.isDone()) {

  23.                try {

  24.                    log.info("result is " + future.get());

  25.                } catch (Exception e) {

  26.                    e.printStackTrace();

  27.                }

  28.                break;

  29.            }

  30.        }

  31.        log.info("finish");

  32.    }

  33.  

  34. }

注意事项

1、使用注意

@Async只能使用到被代理的对象方法上,即代理类的入口方法处,且方法必须是public的。

2、事务处理机制

使用@Async异步注解不能和@Transaction事务注解在同一个方法上同时使用,不然事务注解将无效。

要使用事务,需要把事务注解提取到方法里面的子方法上。

posted @ 2018-06-01 15:32  章鱼哥哥  阅读(297)  评论(0编辑  收藏  举报