Spring Async和Java的8 CompletableFuture

众所周知,我不是Spring的最大粉丝,但当时我在一个组织中工作,该组织使用Spring(以不同的形式和版本)维护了太多项目。 我仍然对Spring持怀疑态度,当然有一些很好的主意,有一些很好的(太多)抽象,也有一些非常方便的“捷径”来引导复杂的项目。 我不会在这篇文章中详细说明我不喜欢的事情。

我喜欢Spring的文档,这是他们的入门指南。 写得好具体。 我正在通过SpringBoot / RestApi [ link ]阅读有关“ 异步 ”方法执行的简短指南。

这就是示例“ asynchronous” findUser()方法的实现。 完整的源代码在这里 。

@Async
public Future findUser(String user) throws InterruptedException {
  System.out.println("Looking up " + user);
  User results = restTemplate.getForObject("https://api.github.com/users/" + user, User.class);
  // Artificial delay of 1s for demonstration purposes
  Thread.sleep(1000L);
  return new AsyncResult(results);
}

我想知道为什么在示例中仍然存在“未来”,而我们已经介绍了Java8 CompletableFuture 。 我猜想原始作者想保持与Java早期版本(6/7)的向后兼容性-在该版本中该构造不可用

似乎其他人也有同样的问题, 在这里写了一个很好的例子。 在其中的一条注释中,您可以看到一个提示,即从4.2版及更高版本开始,Spring API将与已经提供的Future&AsyncResult之上的CompletableFuture兼容。 我认为,“ 很好,这是一个耻辱,为什么不尝试甚至记录下来,因为如果有人使用此示例,他/她可能会保留当前的实现方式 ” –为什么不使用某种标准?

因此,我决定做一个小小的更改,删除Future并用CompletableFuture替换它,还注释掉对Future.isDone()的调用,并用非常方便的CompletableFuture.allof()方法替换它。

因此,我更改了“服务”方法的返回类型,同时更新了调用方代码-以同步所有3个期货,一旦allof()完成,我们就可以打印结果。

package hello;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class GitHubLookupService {

    RestTemplate restTemplate = new RestTemplate();

    @Async
    public CompletableFuture findUser(String user) throws InterruptedException {
        System.out.println("Looking up " + user);
        User results = restTemplate.getForObject("https://api.github.com/users/" + user, User.class);
        // Artificial delay of 1s for demonstration purposes
        Thread.sleep(1000L);
        return CompletableFuture.completedFuture(results);
    }

}

修改后的示例可以在此处找到。 我从Tomasz Nirkewicz找到了这个和这篇博客文章, 这是CompletableFuture丰富方法列表的非常不错且实用的指南。 我最喜欢的Devoxx演讲者Jose Paumard也做了一个非常完整的演讲,您可以在这里找到。

@Override
    public void run(String... args) throws Exception {
        // Start the clock
        long start = System.currentTimeMillis();

        // Kick of multiple, asynchronous lookups
        CompletableFuture page1 = gitHubLookupService.findUser("PivotalSoftware");
        CompletableFuture page2 = gitHubLookupService.findUser("CloudFoundry");
        CompletableFuture page3 = gitHubLookupService.findUser("Spring-Projects");

        // Wait until they are all done
        //while (!(page1.isDone() && page2.isDone() && page3.isDone())) {
          //  Thread.sleep(10); //10-millisecond pause between each check
        //}

        //wait until all they are completed.
        CompletableFuture.allOf(page1,page2,page3).join();
        //I could join as well if interested.

        // Print results, including elapsed time
        System.out.println("Elapsed time: " + (System.currentTimeMillis() - start) +" ms");
        System.out.println(page1.get());
        System.out.println(page2.get());
        System.out.println(page3.get());
    }

链接

  • https://spring.io/guides/gs/async-method/
  • http://geowarin.github.io/completable-futures-with-spring-async.html
  • http://www.nurkiewicz.com/2013/05/java-8-completablefuture-in-action.html
  • http://www.nurkiewicz.com/2013/05/java-8-definitive-guide-to.html
  • https://github.com/javapapo/projects-from-blog/tree/master/spring-async-complfuture

翻译自: https://www.javacodegeeks.com/2016/04/spring-async-javas-8-completablefuture.html

你可能感兴趣的:(Spring Async和Java的8 CompletableFuture)