介绍
@Async:支持自动将普通方法转为异步调用
但是该功能有一个小问题,就是某些业务又需要同步调用时难以实现,特别是返回值为 void 时,这时候只能修改代码兼容两种逻辑
@Async.Await:该注解支持将异步调用自动转为同步调用
直接注解在方法上,那么该方法体的整个调用链路的异步调用都将自动转为同步调用,不仅仅是 @Async 注解的方法,返回值为 Future/CompletionStage 的方法也将自动转为同步调用
下面是代码示例:
package com.kfyty.demo;
import com.kfyty.loveqq.framework.boot.K;
import com.kfyty.loveqq.framework.core.autoconfig.CommandLineRunner;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Async;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.BootApplication;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component;
import com.kfyty.loveqq.framework.core.utils.CommonUtil;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Async
@BootApplication
public class Main implements CommandLineRunner {
@Autowired
private Main main;
@Autowired
private AsyncService asyncService;
@Override
public void run(String... args) throws Exception {
//main.test();
main.testAwait();
}
/**
* 结果输出 0,因为内部调用的是异步方法
*/
public void test() {
asyncService.asyncProcess();
System.out.println(asyncService.getState());
}
/**
* 结果输出 1,因为内部调用异步方法自动转为了同步
*/
@Async.Await
public void testAwait() {
asyncService.asyncProcess();
System.out.println(asyncService.getState());
}
public static void main(String[] args) throws Exception {
K.run(Main.class, args);
}
@Async
@Component
public static class AsyncService {
@Getter
private int state = 0;
@Async
public void asyncProcess() {
// 模拟业务耗时
CommonUtil.sleep(500);
// 修改状态
this.state = 1;
}
}
}
新特性注解源码:
package com.kfyty.loveqq.framework.core.autoconfig.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 描述: 用以支持异步任务
* <b>
* 仅在类上同时注释时,方法注释才有效
* </b>
*
* @author kfyty725
* @date 2021/6/26 11:03
* @email [email protected]
* @see com.kfyty.loveqq.framework.boot.proxy.AsyncMethodInterceptorProxy
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Async {
/**
* 执行该任务的线程池的 bean name,必须是 {@link java.util.concurrent.ExecutorService} 的子类
*/
String value() default "";
/**
* 用于支持异步方法转同步
* 被注解的方法中,当在该方法体中(该方法的整个调用链路中)调用其他异步方法时,其他异步方法自动转为同步调用,而无需显示手动等待
* <p>
* 其他异步方法包含 {@link Async} 注解的方法,以及返回值为 {@link java.util.concurrent.Future}/{@link java.util.concurrent.CompletionStage} 的可代理方法
* <b>
* 仅在类上同时注释 {@link Async} 时,方法注释才有效
* </b>
* </p>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Await {
/**
* 由于整个调用链路有效,因此如果有某个异步方法必须异步,则可以再次注解该方法,并设置为 false,则可以覆盖之前的设置
*
* @return true/false
*/
boolean value() default true;
}
}
感兴趣的同学可以看一下