java - 如何将 CompletableFuture 与 Spring Boot 结合使用以提供可靠的服务

标签 java spring-boot asynchronous

我在理解 SpringBoot 中的异步方法如何工作时遇到了困难。

考虑我正在实现一个微服务来获取用户或全部的当前、处理中或已售出属性,具体取决于用户的查询参数。我正在调用两种方法,它们调用 sql 脚本来给我答案。我想异步运行这些方法,因为这可能需要时间。

示例:

@Service
public class PropertyService {

  public PropertyVO getPropertySummary() {

        CompletableFuture<List<Property>> currentProperty = null;
        CompletableFuture<List<Property>> soldProperty = null;
        CompletableFuture<List<Property>> inProcessProperty = null;

        CompletableFuture<List<Property>> allProperty = null;

        if(status.equals("ALL")) {

            allProperty = propertyDAO.getAllProperty(userId);

        }else {

            String[] statuses = status.split(",");

            for (String st : statuses) {

                if (st.equals("CURRENT")) {

                    currentProperty = propertyDAO.getCurrentProperty(userId);

                } else if (st.equals("SOLD")) {

                    soldProperty = propertyDAO.getSoldProperty(userId);

                } else if (st.equals("IN-Process")) {

                    inProcessProperty = propertyDAO.getInProcessProperty(userId);
                }
            }

            // Do I need this? How would it work when user just needs CURRENT and SOLD. Will it get stuck on IN-PROCESS?
            // CompletableFuture.allOf(currentProperty,soldProperty,inProcessProperty).join();
        }

        // Will it wait here for the above methods to run?
        List<Property> allPropertyList = getResult(allProperty);

        List<Property> currentPropertyList = getResult(currentProperty);
        List<Property> soldPropertyList = getResult(soldProperty);
        List<Property> inProcessPropertyList = getResult(inProcessProperty);

        ..... return Object Property
  }  


  private List<Property> getResult(final CompletableFuture<List<Property>> completableFuture) {

        if(completableFuture == null) {
            return Lists.newArrayList();
        }

        return completableFuture.get(30,TIMEUNIT.SEC);
    }

}  

@Repository
class PropertyRepository {

 @Async
 @Transactional(readOnly = true)
 public CompletableFuture<List<Property>> getCurrentProperty(int userId) {

     String query = sqlRetriever.getQueryByKey("SQL_GET_CURRENT_PROPERTY");

     return CompletableFuture.completedFuture(getNamedParameterJdbcTemplate().query(query,new PropertyMapper()));
}    


@SpringBootApplication
@EnableAsync
public class SpringBootApp {

    /**
     * The entry point into the application.
     *
     * @param args
     */
    public static void main(String[] args) {
        SpringApplication.run(SpringBootApp.class, args).close();
    }

    @Bean
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("Property-");
        executor.initialize();
        return executor;
    }
}

问题:

  • 这个异步调用有效吗?
  • 我需要使用CompletableFuture的join方法吗?它可能会发生 其他 CompletebleFuture 实例可以为 null,如果不是的话
    通过查询参数提供。例如,用户仅提供当前。
  • 我需要提及 @EnableAsync 和 asyncExecutor 吗?

任何帮助将不胜感激,我在线阅读了所有注释,但我仍然有点困惑。我无法在本地运行它,因为我仍然没有完整的代码。

最佳答案

CompletebleFuture 的示例实现:

私有(private)最终ExecutorService ioBound;

  CompletableFuture.supplyAsync(() -> this.getCurrentProperty(record), this.ioBound)
                    .exceptionally(exception -> false)
                    .thenAccept(input -> {
                        if (Boolean.FALSE.equals(input)) {
                            log.error("exception occured:{}", input);
                        } else
                            log.info("Success:{}", input);

                    })

关于java - 如何将 CompletableFuture 与 Spring Boot 结合使用以提供可靠的服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49848366/

相关文章:

java - Java中 boolean 表达式求值顺序?

java - 在 JavaFX FXML Controller 中实现构造函数

基于 Redis 的 Java 作业调度程序?

javascript - 当外部 JavaScript 完成时得到提醒

ios - 异步 NSData 仍在内存中,没有缓存

java - 远程执行shell脚本时找不到"readOnly"等符号

java - 无法打开 JPA 实体管理器

java - 将复杂的 Json 映射到 Pojo 类

java - 如何为所有 Controller 配置默认的@RestController URI 前缀?

c# - Dispatcher.Invoke with anonymous delegate 在 Silverlight 中有效但在 WPF 中无效