代码之家  ›  专栏  ›  技术社区  ›  Jan Testowy

在Spring中使用deferredResult在后台运行任务,而不使用冻结浏览器作为客户端

  •  1
  • Jan Testowy  · 技术社区  · 7 年前

    我实现了一个简单的 Rest service 我想用它来测试 deferredResult Spring

    1. 试验

    我很感兴趣为什么在浏览器(客户端)我需要等待8秒。不是吗 deferedResult Java 9 反应流呢?

    @RestController("/")
    public class Controller {
    
        @GetMapping
        public DeferredResult<Person> test() {
            System.out.println("TEST");
            DeferredResult<Person> result = new DeferredResult<>();
            CompletableFuture.supplyAsync(this::test1)
                    .whenCompleteAsync((res, throwable) -> {
                        System.out.println("TEST AFTER DEFERRED RESULT");
                        result.setResult(res);
                    });
            System.out.println("TEST 1");
            return result;
        }
    
        private Person test1() {
            try {
                Thread.sleep(8000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return new Person("michal", 20);
        }
    }
    
    class Person implements Serializable {
        private String name;
        private int age;
    }
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Bogdan Oros    7 年前

    DeferredResult 是一个 WebRequest setResult setError Web请求 你的客户会收到回应。

    延迟结果 holder是一个用于非阻塞IO线程的Spring框架抽象。 延迟结果抽象与后台任务无关。在没有线程抽象的情况下调用它将导致预期的相同线程执行。你的 test1 CompletableFuture.supplyAsync 为公共池提供执行的方法调用。

    whenCompleteAsync 只有在 测试1 方法将返回。

    当“服务调用逻辑”需要8秒的时间时,您不能立即收到结果,尽管您是在后台执行的。如果您想释放HTTP请求-只需返回一个可用的适当对象(例如,它可以包含一个UUID,以便稍后获取创建的人员)或不从controller方法返回任何内容。你可以试试 GET 您在之后创建的用户 N 得到 您创建的对象。

    第二种方法(如果您应该通知您的客户端-但我不建议您这样做,如果这是唯一的原因)-您可以使用WebSockets通知客户端并与之一起发送消息。