Spring开启方法异步执行
@EnableAsync
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public@interfaceEnableAsync{
Classannotation()defaultAnnotation.class;
booleanproxyTargetClass()defaultfalse;
AdviceModemode()defaultAdviceMode.PROXY;
intorder()defaultOrdered.LOWEST_PRECEDENCE;
}
@EnableAsync注解即开启Spring对方法异步执行的能力,需要和注解@Configuration配合使用。
@Configuration
@EnableAsync
publicclassAppConfig{
}
也可以自定义线程池
@Configuration
@EnableAsync
publicclassAppConfigimplementsAsyncConfigurer{
@Override
publicExecutorgetAsyncExecutor(){
ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor();
executor.setCorePoolSize(7);
executor.setMaxPoolSize(42);
executor.setQueueCapacity(11);
executor.setThreadNamePrefix("MyExecutor-");
executor.initialize();
returnexecutor;
}
@Override
publicAsyncUncaughtExceptionHandlergetAsyncUncaughtExceptionHandler(){
returnMyAsyncUncaughtExceptionHandler();
}
}
@Async
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public@interfaceAsync{
Stringvalue()default"";
}
在要异步执行的方法上使用@Async注解,下面是一个没有返回值,一个带有返回值的异步调用的示例。
@Component
publicclassAsyncTask{
@Async
publicvoidtask1(){
try{
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
@Async
publicFuturetask2(){
try{
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
returnnewAsyncResult("javastack");
}
}
测试代码
@RunWith(SpringRunner.class)
@SpringBootTest
publicclassAsyncTest{
privatefinalstaticLoggerlog=LoggerFactory.getLogger(AsyncTest.class);
@Autowired
privateAsyncTaskasyncTask;
@Test
publicvoidtestTask1(){
log.info("start");
asyncTask.task1();
log.info("finish");
}
@Test
publicvoidtestTask2(){
log.info("start");
Futurefuture=asyncTask.task2();
while(true){
if(future.isDone()){
try{
log.info("result is "+future.get());
}catch(Exceptione){
e.printStackTrace();
}
break;
}
}
log.info("finish");
}
}
注意事项
1、使用注意
@Async只能使用到被代理的对象方法上,即代理类的入口方法处,且方法必须是public的。
2、事务处理机制
使用@Async异步注解不能和@Transaction事务注解在同一个方法上同时使用,不然事务注解将无效。
要使用事务,需要把事务注解提取到方法里面的子方法上。
欢迎大家转发到朋友圈,和朋友们一起提升自己。