SpringBoot Vert.x 四(阻塞Controller)
Vertx 呢 是一套异步框架 当然,理想是美好的,现实是骨感的。
很多实际应用场景中 都会涉及到 阻塞(耗时)操作
举个栗子:
@RequestMapping("findGirlFriend")
public ControllerHandler findGirlFriend() {
return vertxRequest -> {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
vertxRequest.buildVertxRespone().respone(new ResponeWrapper(10001, null, "girl friend not found"));
};
}
这时候 控制台应该输出了一些错误日志
那对于这种阻塞(耗时)操作的接口,Vertx也有对应的处理
新增一个注解
/**
* blocking handler
*
* @author pencilso
* @date 2020/1/24 9:59 上午
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestBlockingHandler {
}
再次改造 VerticleMain 类 里的registerControllerMethod 方法 (这个类已经改造了好多次了 啊哈哈)
判断是否在方法上 或者 类上面 添加了 @RequestBlockingHandler 注解
/**
* register controller method
*
* @param router route
* @param classRequestMapping controller requestMapping annotation
* @param controllerClass controller class
* @param controller controller instance
*/
private void registerControllerMethod(@NotNull Router router, @NotNull RequestMapping classRequestMapping, @NotNull Class<?> controllerClass, @NotNull Object controller) {
//获取控制器里的方法
Method[] controllerClassMethods = controllerClass.getMethods();
Arrays.asList(controllerClassMethods).stream()
.filter(method -> method.getAnnotation(RequestMapping.class) != null)
.forEach(method -> {
try {
RequestMapping methodRequestMapping = method.getAnnotation(RequestMapping.class);
String superPath = classRequestMapping.value()[0];
String methodPath = methodRequestMapping.value()[0];
//if api path empty skip
if (StringUtils.isEmpty(superPath) || StringUtils.isEmpty(methodPath)) return;
String url = VerticleUtils.buildApiPath(superPath, methodPath);
//build route
Route route = VerticleUtils.buildRouterUrl(url, router, methodRequestMapping.method());
//run controller method get Handler object
Handler<RoutingContext> methodHandler = (Handler<RoutingContext>) method.invoke(controller);
//register controller mthod Handler object
RequestBlockingHandler requestBlockingHandler = Optional.ofNullable(method.getAnnotation(RequestBlockingHandler.class)).orElseGet(() -> controllerClass.getAnnotation(RequestBlockingHandler.class));
if (requestBlockingHandler != null) {
//register blocking handler
route.blockingHandler(methodHandler);
} else {
route.handler(methodHandler);
}
log.info("register controller -> [{}] method -> [{}] url -> [{}] ", controllerClass.getName(), method.getName(), url);
} catch (Exception e) {
log.error("registerControllerMethod fail controller: [{}] method: [{}]", controllerClass, method.getName());
}
});
}
现在给 findGirlFriend 方法 添加注解 @RequestBlockingHandler
@RequestBlockingHandler
@RequestMapping("findGirlFriend")
public ControllerHandler findGirlFriend() {
return vertxRequest -> {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
vertxRequest.buildVertxRespone().respone(new ResponeWrapper(10001, null, "girl friend not found"));
};
}
再次访问接口 控制台不再报错了 。