簡體   English   中英

如何與 CompletableFuture 一起使用 SpringBoot 實現寧靜服務

[英]How to work with CompletableFuture with SpringBoot for restful service

我在理解 SpringBoot 中異步方法的工作方式時遇到了麻煩。

考慮我正在實現一個微服務來獲取用戶或所有的 Current、In-process 或 SoldOff 屬性,具體取決於來自用戶的查詢參數。 我正在調用兩種調用 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 的示例實現:

私有最終 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);

                    })
CompletableFuture<String> future1  
  = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2  
  = CompletableFuture.supplyAsync(() -> "Beautiful");
CompletableFuture<String> future3  
  = CompletableFuture.supplyAsync(() -> "World");

CompletableFuture<Void> combinedFuture 
  = CompletableFuture.allOf(future1, future2, future3);

// ...

combinedFuture.get();

assertTrue(future1.isDone());
assertTrue(future2.isDone());
assertTrue(future3.isDone());

請在此處查看第 8 節 - 並行運行多個期貨

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM