Spring开启方法异步执行

时间:2022-05-06
本文章向大家介绍Spring开启方法异步执行,主要内容包括@EnableAsync、@Async、注意事项、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

@EnableAsync

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {

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

    boolean proxyTargetClass() default false;

    AdviceMode mode() default AdviceMode.PROXY;

    int order() default Ordered.LOWEST_PRECEDENCE;

}

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

@Configuration
@EnableAsync
public class AppConfig {

}

也可以自定义线程池

@Configuration
 @EnableAsync
 public class AppConfig implements AsyncConfigurer {

     @Override
     public Executor getAsyncExecutor() {
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
         executor.setCorePoolSize(7);
         executor.setMaxPoolSize(42);
         executor.setQueueCapacity(11);
         executor.setThreadNamePrefix("MyExecutor-");
         executor.initialize();
         return executor;
     }

     @Override
     public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
         return MyAsyncUncaughtExceptionHandler();
     }
 }

@Async

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Async {

    String value() default "";

}

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

@Component
public class AsyncTask {

    @Async
    public void task1() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Async
    public Future<String> task2() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new AsyncResult<String>("javastack");  
    }

}

测试代码

@RunWith(SpringRunner.class)
@SpringBootTest
public class AsyncTest {

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

    @Autowired
    private AsyncTask asyncTask;

    @Test
    public void testTask1(){
        log.info("start");
        asyncTask.task1();
        log.info("finish");
    }

    @Test
    public void testTask2()  {
        log.info("start");
        Future<String> future = asyncTask.task2();
        while (true) {
            if (future.isDone()) {
                try {
                    log.info("result is " + future.get());
                } catch (Exception e) {
                    e.printStackTrace();
                } 
                break;
            }
        }
        log.info("finish");
    }

}

注意事项

1、使用注意

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

2、事务处理机制

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

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

看完有没有收获?

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