查看原文
其他

Spring开启方法异步执行

2017-08-25 javastack Java技术栈


@EnableAsync

  1. @Target(ElementType.TYPE)

  2. @Retention(RetentionPolicy.RUNTIME)

  3. @Documented

  4. @Import(AsyncConfigurationSelector.class)

  5. public @interface EnableAsync {

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

  7.    boolean proxyTargetClass() default false;

  8.    AdviceMode mode() default AdviceMode.PROXY;

  9.    int order() default Ordered.LOWEST_PRECEDENCE;

  10. }

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

  1. @Configuration

  2. @EnableAsync

  3. public class AppConfig {

  4. }

也可以自定义线程池

  1. @Configuration

  2. @EnableAsync

  3. public class AppConfig implements AsyncConfigurer {

  4.     @Override

  5.     public Executor getAsyncExecutor() {

  6.         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

  7.         executor.setCorePoolSize(7);

  8.         executor.setMaxPoolSize(42);

  9.         executor.setQueueCapacity(11);

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

  11.         executor.initialize();

  12.         return executor;

  13.     }

  14.     @Override

  15.     public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {

  16.         return MyAsyncUncaughtExceptionHandler();

  17.     }

  18. }

@Async

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

  2. @Retention(RetentionPolicy.RUNTIME)

  3. @Documented

  4. public @interface Async {

  5.    String value() default "";

  6. }

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

  1. @Component

  2. public class AsyncTask {

  3.    @Async

  4.    public void task1() {

  5.        try {

  6.            Thread.sleep(3000);

  7.        } catch (InterruptedException e) {

  8.            e.printStackTrace();

  9.        }

  10.    }

  11.    @Async

  12.    public Future<String> task2() {

  13.        try {

  14.            Thread.sleep(3000);

  15.        } catch (InterruptedException e) {

  16.            e.printStackTrace();

  17.        }

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

  19.    }

  20. }

测试代码

  1. @RunWith(SpringRunner.class)

  2. @SpringBootTest

  3. public class AsyncTest {

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

  5.    @Autowired

  6.    private AsyncTask asyncTask;

  7.    @Test

  8.    public void testTask1(){

  9.        log.info("start");

  10.        asyncTask.task1();

  11.        log.info("finish");

  12.    }

  13.    @Test

  14.    public void testTask2()  {

  15.        log.info("start");

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

  17.        while (true) {

  18.            if (future.isDone()) {

  19.                try {

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

  21.                } catch (Exception e) {

  22.                    e.printStackTrace();

  23.                }

  24.                break;

  25.            }

  26.        }

  27.        log.info("finish");

  28.    }

  29. }

注意事项

1、使用注意

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

2、事务处理机制

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

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

看完有没有收获?

分享到朋友圈给更多的人吧。





您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存