一、DeferredResult概述
DeferredResult是一個Spring MVC的技術,它允許把請求處理的結果異步的發送到客戶端。當一個請求被接收時,處理器通常會立即返回一個代表結果的DeferredResult對象。在這個處理器方法中,DeferredResult對象相當於一個Promise(承諾):它之後會被填充結果,而這個結果在另外一個線程中進行。這種方法允許處理器方法的執行在結果可以被填充之前就立即結束。
@Controller @RequestMapping("/deferredresult") public class DeferredResultController { private final Queue<DeferredResult> deferredResults = new ConcurrentLinkedQueue(); @GetMapping("/") public DeferredResult handleRequest() { final DeferredResult deferredResult = new DeferredResult(); deferredResults.add(deferredResult); return deferredResult; } @PostMapping("/") public String processRequest(@RequestBody String message) { deferredResults.forEach(deferredResult -> deferredResult.setResult(message)); deferredResults.clear(); return "processed"; } }
二、DeferredResult的優勢
DeferredResult最大的優勢在於它可以解決長時間運行的請求超時問題。例如,假設你有一個在後台執行的任務,這個任務需要一段時間才能完成。如果瀏覽器與服務器之間的連接時間太長,瀏覽器可能會將連接關閉,從而導致服務器在任務完成之前就終止。
另一個優勢是,通過使用DeferredResult,你可以將請求發送到一個處理器方法,然後你可以在請求返回到該方法之前立即返迴響應。這樣可以極大地提高應用程序的吞吐量,並允許處理器方法在發送請求之後進行其他的工作。
三、使用DeferredResult的注意事項
1、DeferredResult需要在不同的線程中填充結果,否則會阻塞請求線程,導致不可預測的結果。要確保DeferredResult被填充到另一個線程中,可以使用Spring的異步調用機制,或者開啟一個新的線程。
2、如果處理程序可能會永遠無法填充DeferredResult,則應該設置一個空結果,以便防止客戶端永遠等待。
3、對於每個請求,都應該創建一個新的DeferredResult對象,而不是在多個請求之間共享它們。
四、DeferredResult使用示例
下面是一個使用DeferredResult的示例,它將打印出deferredResult對象的狀態,並返回一個字符串到客戶端:
@GetMapping("/longRunningRequest") public DeferredResult handleLongRunningRequest() { // 創建一個新的DeferredResult final DeferredResult deferredResult = new DeferredResult(); // 將DeferredResult的結果放到一個新的線程中,以避免阻塞請求線程 new Thread(() -> { try { // 模擬長時間運行的任務 Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } // 將結果填充到DeferredResult deferredResult.setResult("Long running request completed"); }).start(); // 返回DeferredResult對象 return deferredResult; }
五、結語
DeferredResult是一個非常有用的技術,特別是在處理需要長時間運行的請求或需要等待外部資源的請求時。當使用它時,請確保遵循最佳實踐並遵循你的應用程序的特定需求。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/251941.html