У меня есть модель:
package com.example.asyncmethod;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown=true)
public class User {
private String name;
private String blog;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBlog() {
return blog;
}
public void setBlog(String blog) {
this.blog = blog;
}
@Override
public String toString() {
return "User [name=" + name + ", blog=" + blog + "]";
}
}
вызов службы, как показано ниже
package com.example.asyncmethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.concurrent.CompletableFuture;
@Service
public class GitHubLookupService {
private static final Logger logger = LoggerFactory.getLogger(GitHubLookupService.class);
private final RestTemplate restTemplate;
public GitHubLookupService(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
}
@Async
public CompletableFuture<User> findUser(Integer user) throws InterruptedException {
logger.info("Looking up " + user);
String url = String.format("https://api.github.com/users/%s", user);
User results = restTemplate.getForObject(url, User.class);
Thread.sleep(1000L);
return CompletableFuture.completedFuture(results);
}
}
Класс асинхронного бегуна:
package com.example.asyncmethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.concurrent.CompletableFuture;
@Component
public class AppRunner implements CommandLineRunner {
private static final Logger logger = LoggerFactory.getLogger(AppRunner.class);
private final GitHubLookupService gitHubLookupService;
public AppRunner(GitHubLookupService gitHubLookupService) {
this.gitHubLookupService = gitHubLookupService;
}
@Override
public void run(String... args) throws Exception {
// Start the clock
long start = System.currentTimeMillis();
// in real use case before the for loop I will have a database call to get the number of records and based on the size I need to call that many number of times.
for(int i=0; i <= 10; i++){
CompletableFuture<User> page1 = gitHubLookupService.findUser(1);
}
// Wait until they are all done
CompletableFuture.allOf(page1).join();
// Print results, including elapsed time
logger.info("Elapsed time: " + (System.currentTimeMillis() - start));
logger.info("--> " + page1.get());
}
}
Итак, в приведенном выше цикле for я мог бы вызвать findUser в соответствии с количеством записей, возвращаемых БД.
Также в будущем мне может потребоваться добавить еще несколько асинхронных вызовов, таких как findOrders, findInventory, findAccess и т. Д., Которые будут вызывать другие службы через http.
Учитывая, что асинхронный вызов может быть успешным для одной записи и терпеть неудачу для другой записи, как я могу подойти здесь, чтобы вызвать асинхронный вызов наилучшим образом?