Skip to content

Commit

Permalink
重构 ScxWeb 避免每次都查找 参数处理器 (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
scx567888 authored Nov 5, 2024
1 parent 6781838 commit 1281b0c
Show file tree
Hide file tree
Showing 22 changed files with 381 additions and 167 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public interface ScxConfigSource {
ObjectNode configMapping();

default void onChange(BiConsumer<ObjectNode, ObjectNode> changeHandler) {

}

}
10 changes: 6 additions & 4 deletions scx-ext/src/main/java/cool/scx/ext/crud/CRUDModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import cool.scx.core.Scx;
import cool.scx.core.ScxModule;
import cool.scx.ext.crud.parameter_handler.crud_list_param.CRUDListParamParameterHandlerBuilder;
import cool.scx.ext.crud.parameter_handler.crud_update_param.CRUDUpdateParamParameterHandlerBuilder;

import static java.lang.System.Logger;
import static java.lang.System.Logger.Level.DEBUG;
Expand Down Expand Up @@ -33,10 +35,10 @@ public CRUDModule() {
@Override
public void start(Scx scx) {
//这里添加额外的参数处理器 保证 CRUDListParam 类型的参数永不为空
scx.scxWeb().addParameterHandler(0, cool.scx.ext.crud.CRUDListParamMethodParameterHandler.DEFAULT_INSTANCE);
scx.scxWeb().addParameterHandler(0, cool.scx.ext.crud.CRUDUpdateParamMethodParameterHandler.DEFAULT_INSTANCE);
logger.log(DEBUG, "已添加用于处理类型为 CRUDListParam 的 MethodParameterHandler --> {0}", CRUDListParamMethodParameterHandler.class.getName());
logger.log(DEBUG, "已添加用于处理类型为 CRUDUpdateParam 的 MethodParameterHandler --> {0}", CRUDUpdateParamMethodParameterHandler.class.getName());
scx.scxWeb().addParameterHandlerBuilder(0, new CRUDListParamParameterHandlerBuilder());
scx.scxWeb().addParameterHandlerBuilder(0, new CRUDUpdateParamParameterHandlerBuilder());
logger.log(DEBUG, "已添加用于处理类型为 CRUDListParam 的 ParameterHandlerBuilder --> {0}", CRUDListParamParameterHandlerBuilder.class.getName());
logger.log(DEBUG, "已添加用于处理类型为 CRUDUpdateParam 的 ParameterHandlerBuilder --> {0}", CRUDUpdateParamParameterHandlerBuilder.class.getName());
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,31 @@
package cool.scx.ext.crud;
package cool.scx.ext.crud.parameter_handler.crud_list_param;

import cool.scx.ext.crud.CRUDListParam;
import cool.scx.reflect.ParameterInfo;
import cool.scx.web.parameter_handler.ParameterHandler;
import cool.scx.web.parameter_handler.RequestInfo;

import static cool.scx.web.parameter_handler.FromBodyParameterHandler.getValueFromBody;
import static cool.scx.web.parameter_handler.from_body.FromBodyParameterHandler.getValueFromBody;

/**
* a
*
* @author scx567888
* @version 1.10.8
*/
public final class CRUDListParamMethodParameterHandler implements ParameterHandler {
public final class CRUDListParamParameterHandler implements ParameterHandler {

/**
* a
*/
public static final CRUDListParamMethodParameterHandler DEFAULT_INSTANCE = new CRUDListParamMethodParameterHandler();
private final ParameterInfo parameter;

/**
* {@inheritDoc}
*/
@Override
public boolean canHandle(ParameterInfo parameter) {
return parameter.type().getRawClass() == CRUDListParam.class;
public CRUDListParamParameterHandler(ParameterInfo parameter) {
this.parameter = parameter;
}

/**
* {@inheritDoc}
*/
@Override
public Object handle(ParameterInfo parameter, RequestInfo requestInfo) throws Exception {
public Object handle(RequestInfo requestInfo) throws Exception {
var javaType = parameter.type();
var name = parameter.name();
var required = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package cool.scx.ext.crud.parameter_handler.crud_list_param;

import cool.scx.ext.crud.CRUDListParam;
import cool.scx.reflect.ParameterInfo;
import cool.scx.web.parameter_handler.ParameterHandler;
import cool.scx.web.parameter_handler.ParameterHandlerBuilder;

public class CRUDListParamParameterHandlerBuilder implements ParameterHandlerBuilder {

@Override
public ParameterHandler tryBuild(ParameterInfo parameter) {
if (parameter.type().getRawClass() != CRUDListParam.class) {
return null;
}
return new CRUDListParamParameterHandler(parameter);
}

}
Original file line number Diff line number Diff line change
@@ -1,37 +1,31 @@
package cool.scx.ext.crud;
package cool.scx.ext.crud.parameter_handler.crud_update_param;

import cool.scx.ext.crud.CRUDUpdateParam;
import cool.scx.reflect.ParameterInfo;
import cool.scx.web.parameter_handler.ParameterHandler;
import cool.scx.web.parameter_handler.RequestInfo;

import static cool.scx.web.parameter_handler.FromBodyParameterHandler.getValueFromBody;
import static cool.scx.web.parameter_handler.from_body.FromBodyParameterHandler.getValueFromBody;

/**
* a
*
* @author scx567888
* @version 1.10.8
*/
public final class CRUDUpdateParamMethodParameterHandler implements ParameterHandler {
public final class CRUDUpdateParamParameterHandler implements ParameterHandler {

/**
* a
*/
public static final CRUDUpdateParamMethodParameterHandler DEFAULT_INSTANCE = new CRUDUpdateParamMethodParameterHandler();
private final ParameterInfo parameter;

/**
* {@inheritDoc}
*/
@Override
public boolean canHandle(ParameterInfo parameter) {
return parameter.type().getRawClass() == CRUDUpdateParam.class;
public CRUDUpdateParamParameterHandler(ParameterInfo parameter) {
this.parameter = parameter;
}

/**
* {@inheritDoc}
*/
@Override
public Object handle(ParameterInfo parameter, RequestInfo requestInfo) throws Exception {
public Object handle(RequestInfo requestInfo) throws Exception {
var javaType = parameter.type();
var name = parameter.name();
var required = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package cool.scx.ext.crud.parameter_handler.crud_update_param;

import cool.scx.ext.crud.CRUDUpdateParam;
import cool.scx.reflect.ParameterInfo;
import cool.scx.web.parameter_handler.ParameterHandler;
import cool.scx.web.parameter_handler.ParameterHandlerBuilder;

/**
* a
*
* @author scx567888
* @version 1.10.8
*/
public final class CRUDUpdateParamParameterHandlerBuilder implements ParameterHandlerBuilder {

@Override
public ParameterHandler tryBuild(ParameterInfo parameter) {
if (parameter.type().getRawClass() != CRUDUpdateParam.class) {
return null;
}
return new CRUDUpdateParamParameterHandler(parameter);
}

}
5 changes: 4 additions & 1 deletion scx-web/src/main/java/cool/scx/web/ScxRouteHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import cool.scx.http.routing.RoutingContext;
import cool.scx.reflect.MethodInfo;
import cool.scx.web.annotation.ScxRoute;
import cool.scx.web.parameter_handler.ParameterHandler;

import java.lang.reflect.InvocationTargetException;
import java.util.Set;
Expand All @@ -38,6 +39,7 @@ public final class ScxRouteHandler implements Route, Consumer<RoutingContext> {
private final int order;
private final PathMatcher pathMatcher;
private final MethodMatcher methodMatcher;
private final ParameterHandler[] parameterHandlers;

ScxRouteHandler(MethodInfo method, Object instance, ScxWeb scxWeb) {
this.scxWeb = scxWeb;
Expand All @@ -54,6 +56,7 @@ public final class ScxRouteHandler implements Route, Consumer<RoutingContext> {
this.order = methodAnnotation.order();
this.pathMatcher = path.isBlank() ? PathMatcher.any() : PathMatcher.of(path);
this.methodMatcher = methods.isEmpty() ? MethodMatcher.any() : MethodMatcher.of(methods.toArray(ScxHttpMethod[]::new));
this.parameterHandlers = scxWeb.buildParameterHandlers(this.method.parameters());
}

private String initPath(ScxRoute classAnnotation, ScxRoute methodAnnotation) {
Expand Down Expand Up @@ -84,7 +87,7 @@ public void accept(RoutingContext context) {
//1, 执行前置处理器 (一般用于校验权限之类)
this.scxWeb.interceptor().preHandle(context, this);
//2, 根据 method 参数获取 invoke 时的参数
var methodParameters = this.scxWeb.buildMethodParameters(this.method.parameters(), context);
var methodParameters = this.scxWeb.buildMethodParameters(parameterHandlers, context);
//3, 执行具体方法 (用来从请求中获取参数并执行反射调用方法以获取返回值)
var tempResult = this.method.method().invoke(this.instance, methodParameters);
//4, 执行后置处理器
Expand Down
59 changes: 38 additions & 21 deletions scx-web/src/main/java/cool/scx/web/ScxWeb.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,17 @@
import cool.scx.web.exception_handler.ScxHttpExceptionHandler;
import cool.scx.web.interceptor.DefaultInterceptor;
import cool.scx.web.interceptor.Interceptor;
import cool.scx.web.parameter_handler.*;
import cool.scx.web.parameter_handler.ParameterHandler;
import cool.scx.web.parameter_handler.ParameterHandlerBuilder;
import cool.scx.web.parameter_handler.RequestInfo;
import cool.scx.web.parameter_handler.exception.ParamConvertException;
import cool.scx.web.parameter_handler.exception.RequiredParamEmptyException;
import cool.scx.web.parameter_handler.from_body.FromBodyParameterHandlerBuilder;
import cool.scx.web.parameter_handler.from_context.FromContextParameterHandlerBuilder;
import cool.scx.web.parameter_handler.from_path.FromPathParameterHandlerBuilder;
import cool.scx.web.parameter_handler.from_query.FromQueryParameterHandlerBuilder;
import cool.scx.web.parameter_handler.from_upload.FromUploadParameterHandlerBuilder;
import cool.scx.web.parameter_handler.last.LastParameterHandlerBuilder;
import cool.scx.web.return_value_handler.*;
import cool.scx.web.template.ScxTemplateHandler;

Expand All @@ -32,8 +40,8 @@ public final class ScxWeb {
private final LastExceptionHandler lastExceptionHandler;
private final List<ReturnValueHandler> returnValueHandlers = new ArrayList<>();
private final LastReturnValueHandler lastReturnValueHandler;
private final List<ParameterHandler> parameterHandlers = new ArrayList<>();
private final LastParameterHandler lastParameterHandler;
private final List<ParameterHandlerBuilder> parameterHandlerBuilders = new ArrayList<>();
private final LastParameterHandlerBuilder lastParameterHandlerBuilder;
private final ScxTemplateHandler templateHandler;
private final RouterErrorHandler routerErrorHandler;
private final RouteRegistrar routeRegistrar;
Expand All @@ -59,12 +67,12 @@ public ScxWeb(ScxWebOptions options) {
addReturnValueHandler(new BaseVoReturnValueHandler());
this.lastReturnValueHandler = new LastReturnValueHandler();
//初始化默认的参数处理器
addParameterHandler(new RoutingContextParameterHandler());
addParameterHandler(new FileUploadParameterHandler());
addParameterHandler(new FromBodyParameterHandler());
addParameterHandler(new FromQueryParameterHandler());
addParameterHandler(new FromPathParameterHandler());
this.lastParameterHandler = new LastParameterHandler();
addParameterHandlerBuilder(new FromContextParameterHandlerBuilder());
addParameterHandlerBuilder(new FromUploadParameterHandlerBuilder());
addParameterHandlerBuilder(new FromBodyParameterHandlerBuilder());
addParameterHandlerBuilder(new FromQueryParameterHandlerBuilder());
addParameterHandlerBuilder(new FromPathParameterHandlerBuilder());
this.lastParameterHandlerBuilder = new LastParameterHandlerBuilder();
}

/**
Expand Down Expand Up @@ -114,8 +122,8 @@ public ScxWeb addExceptionHandler(ExceptionHandler exceptionHandler) {
return this;
}

public ScxWeb addParameterHandler(ParameterHandler handler) {
parameterHandlers.add(handler);
public ScxWeb addParameterHandlerBuilder(ParameterHandlerBuilder handlerBuilder) {
parameterHandlerBuilders.add(handlerBuilder);
return this;
}

Expand All @@ -129,8 +137,8 @@ public ScxWeb addExceptionHandler(int index, ExceptionHandler handler) {
return this;
}

public ScxWeb addParameterHandler(int index, ParameterHandler handler) {
parameterHandlers.add(index, handler);
public ScxWeb addParameterHandlerBuilder(int index, ParameterHandlerBuilder handlerBuilder) {
parameterHandlerBuilders.add(index, handlerBuilder);
return this;
}

Expand Down Expand Up @@ -166,22 +174,23 @@ ReturnValueHandler findReturnValueHandler(Object result) {
}

ParameterHandler findParameterHandler(ParameterInfo parameter) {
for (var handler : parameterHandlers) {
if (handler.canHandle(parameter)) {
return handler;
for (var handler : parameterHandlerBuilders) {
var parameterHandler = handler.tryBuild(parameter);
if (parameterHandler != null) {
return parameterHandler;
}
}
return lastParameterHandler;
return lastParameterHandlerBuilder.tryBuild(parameter);
}

Object[] buildMethodParameters(ParameterInfo[] parameters, RoutingContext context) throws Exception {
Object[] buildMethodParameters(ParameterHandler[] parameterHandlers, RoutingContext context) throws Exception {
var info = new RequestInfo(context);
var exceptionArrayList = new ArrayList<Exception>();
var methodParameter = new Object[parameters.length];
var methodParameter = new Object[parameterHandlers.length];
for (int i = 0; i < methodParameter.length; i = i + 1) {
var methodParameterHandler = findParameterHandler(parameters[i]);
var methodParameterHandler = parameterHandlers[i];
try {
methodParameter[i] = methodParameterHandler.handle(parameters[i], info);
methodParameter[i] = methodParameterHandler.handle(info);
} catch (ParamConvertException | RequiredParamEmptyException e) {
exceptionArrayList.add(e);
}
Expand All @@ -192,6 +201,14 @@ Object[] buildMethodParameters(ParameterInfo[] parameters, RoutingContext contex
return methodParameter;
}

ParameterHandler[] buildParameterHandlers(ParameterInfo[] parameters) {
var s = new ParameterHandler[parameters.length];
for (int i = 0; i < parameters.length; i = i + 1) {
s[i] = findParameterHandler(parameters[i]);
}
return s;
}

public ScxWeb bindErrorHandler(Router vertxRouter) {
vertxRouter.errorHandler(routerErrorHandler);
return this;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package cool.scx.web.parameter_handler;

import cool.scx.reflect.ParameterInfo;

/**
* 参数处理器
*
Expand All @@ -10,22 +8,13 @@
*/
public interface ParameterHandler {

/**
* 判断是否可以处理这个参数类型
*
* @param parameter 参数实例
* @return 是否能够处理
*/
boolean canHandle(ParameterInfo parameter);

/**
* 将结果处理并返回
*
* @param parameter 方法参数
* @param requestInfo 包装后的 RoutingContext
* @return 处理后的结果
* @throws java.lang.Exception e
*/
Object handle(ParameterInfo parameter, RequestInfo requestInfo) throws Exception;
Object handle(RequestInfo requestInfo) throws Exception;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cool.scx.web.parameter_handler;

import cool.scx.reflect.ParameterInfo;

/**
* 参数处理器
*
* @author scx567888
* @version 1.11.8
*/
public interface ParameterHandlerBuilder {

/**
* 判断是否可以处理这个参数类型 返回 null 不支持
*
* @param parameter 参数实例
* @return 参数处理器 (为 null 表示不支持)
*/
ParameterHandler tryBuild(ParameterInfo parameter);

}

This file was deleted.

Loading

0 comments on commit 1281b0c

Please sign in to comment.