我有@SpringBootApplication
,其中@RestController
处理着@GetMapping("/math/square")
端点。
例如,请求GET /math/square?x=2
返回{result:4}
我想将数学业务逻辑委托给与端点分开的另一个过程。
在春季推荐的方法是什么?
答案 0 :(得分:0)
根据我的收集,您希望数学业务逻辑异步发生。 首先,如果您不是出于“教育目的”这样做,或者实际逻辑不是很费时,那么我建议您不要这样做,因为对我而言这是过早的优化。
我查看了您的个人资料,看来主导标记是Go语言,所以也许这就是您编写“ process”的原因。但是我要说的是,产生另一个进程太重了(而且很麻烦)。我认为,在单独的线程中执行逻辑是更好的选择。
在Spring中实现此目标的一种方法是使用DeferredResult类。它充当正在进行的计算的容器。您可以从控制器返回此类的对象,而不会阻塞处理请求的http-worker线程,并在后台完成计算。我认为最好用一个简单的例子来解释。
@RestController
public class MathController {
private static final Logger logger = LoggerFactory.getLogger(MathController.class);
@GetMapping(value = "/math/square")
public DeferredResult<Integer> computeSquare(@RequestParam("x") int x) {
logger.info("Delegating the computation to another thread");
DeferredResult<Integer> deferredResult = new DeferredResult<>();
new Thread(() -> { // normally, you would probably use a thread pool
// here's where the "heavy logic" takes place
logger.info("Computing the square of {}", x);
try {
Thread.sleep(1000); // let's say that it takes some time for demonstration purposes
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("Setting the result");
deferredResult.setResult(x * x);
}).start();
logger.info("Done handling the request");
return deferredResult;
}
}
通过查看示例日志记录语句,我们可以确认http-worker线程(nio-8080-exec-1)没有等待计算完成。当然,发送HTTP请求的客户端将获得结果,因为HTTP连接一直保持打开状态,直到解析deferredResult
。
2018-06-22 01:05:02.146 INFO 13144 --- [nio-8080-exec-1] c.e.s.s.controllers.MathController : Delegating the computation to another thread
2018-06-22 01:05:02.154 INFO 13144 --- [nio-8080-exec-1] c.e.s.s.controllers.MathController : Done handling the request
2018-06-22 01:05:02.154 INFO 13144 --- [ Thread-14] c.e.s.s.controllers.MathController : Computing the square of 2
2018-06-22 01:05:03.156 INFO 13144 --- [ Thread-14] c.e.s.s.controllers.MathController : Setting the result