神刀安全网

Spring Async and Java’s 8 CompletableFuture

It is known that I am not the biggest fan of Spring , but at the time being I work for an organization that maintains too many projects utilizing Spring (in different forms and versions). I still remain skeptic towards Spring, of course there are some very nice ideas, there are some nice (too many) abstractions, there are some very handy ‘shortcuts’ to bootstrap complex projects. I am not going to elaborate on the things I don’t like in this post.

One thing I like on Spring’s documentation, is their getting started guides. Well written and concrete. I was reading through, a short guide, for ‘ Async ‘ method execution, through  SpringBoot /RestApi [  link ] .

So this is this the implementation of the example ‘asynchronous’ findUser() method. Full source here .

@Async public Future<User> 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<User>(results); }

I was wondering why there is still a ‘ Future’ in the example, while we have been introduced Java8, CompletableFutureI guess the original authors want to preserve backwards compatibility with previous versions of Java (6 / 7 ) – where this construct is not available .

It seems that someone else had the same question, and wrote a very nice example here . In one of the comments, you can see a hint that from  version 4.2 and onward the Spring API, would be compatible with the use of CompletableFuture, on top of Future & AsyncResult which are already provided. I thought, `  well it’s a shame, why not try it or even document it, because if someone lands on this example, he/she might stay with the current implementation ` – why not use something standard?.

So I decided to make a tiny change, remove Future and replace it with CompletableFuture, also comment out the calls to Future.isDone() and replace it with the very handy  CompletableFuture.allof() method.

So I changed the return type on the ‘service’ method while, updating the, caller code – to sync on all 3 futures and once allof() them were done, we could print the results.

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);     }  }

The modified, example can be found here . I found  this and  this blog posts from  Tomasz Nirkewicz , a very nice and pragmatic walk through of CompletableFuture, rich method list. There is also a quite complete presentation by my favorite  Devoxx Speaker ,  Jose Paumard you can find it  here .

@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());     }

Links

Reference: Spring Async and Java’s 8 CompletableFuture from ourJCG partner Paris Apostolopoulos at the Papo’s log blog.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Spring Async and Java’s 8 CompletableFuture

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址