java—我可以在SpringBoot中不等待其他外部api调用而返回api响应吗?

uajslkp6  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(653)

这是正确的使用方法吗 @Async 在春靴里?

@Service
class someServiceImpl {
...
  public someResponseDTO getUsers(int userId) {
   // Do some logic
   ...
   // Call external API with another service method from another service impl
   anotherService.emailUserInTheBackground(userId);
   return someResponseDTO;
  }
...
}
@Service
public class AnotherService {
  @Async
  public void emailUserInTheBackground(int userId) {
    // This might take a while...
    ...
  }
}

emailUserInTheBackground()@Async 注解和 void 返回类型,是否阻塞线路 return someResponseDTO 完全?
我只想把响应返回给调用者而不用等待,因为 emailUserInTheBackground() 完成时间太长,并且没有直接绑定到响应对象。

disho6za

disho6za1#

相关行为 @Async 记录在spring文档中:
你可以提供 @Async 方法上的注解,以便异步调用该方法。换句话说,调用方在调用时立即返回,而方法的实际执行发生在已提交给spring的任务中 TaskExecutor .
在你描述的情况下,自从 emailUserInTheBackground 方法的注解为 @Async 如果启用了spring的异步方法执行功能 emailUserInTheBackground 方法将立即返回,调用将在单独的线程中处理。这个 someResponseDTO 值将从 getUsers 方法,而 emailUserInTheBackground 方法继续在后台处理。

k4aesqcs

k4aesqcs2#

是的,这是在后台运行任务的正确方法,您可以通过引入延迟来模拟线程阻塞行为。

@SpringBootApplication
@EnableAsync
public class MyApplication {

    public static void main(String[] arg) {
       SpringApplication.run(MyApplication.class);
    }
}

然后您需要用 @Async 注解。

@Service
class AnotherService {

    @Async
    public void emailUserInTheBackground(int userId) {
       try {
          TimeUnit.SECONDS.sleep(10);
          System.out.println("Print from async: "+ Thread.currentThread().getName());
       } catch (InterruptedException e) {
          e.printStackTrace();
       }
    }
}

现在在方法调用之后再添加一个记录器,您将看到 getUsers(...) 在另一个线程中首先完成调用,即使emailservice线程被阻塞了10秒。

anotherService.emailUserInTheBackground(userId);
System.out.println("Print from service: "+ Thread.currentThread().getName());

您还可以使用completablefuture在后台运行任务。

public someResponseDTO getUsers(int userId) {
   // Do some logic
   ...
   // Call external API with another service method from another service impl
   CompletableFuture.runAsync(() -> anotherService.emailUserInTheBackground(userId)) 
   return someResponseDTO;
  }

相关问题