介绍
@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; } }
感兴趣的同学可以看一下
还没有评论,来说两句吧...