Spring开启方法异步执行
@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事务注解在同一个方法上同时使用,不然事务注解将无效。
要使用事务,需要把事务注解提取到方法里面的子方法上。