Today Web Mvc 参数处理器设计

发布于: 2019年09月03日 23:54:47 | 分类: 轮子工厂 | 浏览: 43

系列博文:《Today Web Mvc 设计思想》之参数处理器设计。

重要接口 ParameterResolver

@FunctionalInterface
public interface ParameterResolver {

    default boolean supports(final MethodParameter parameter) {
        return true;
    }

    Object resolveParameter(final RequestContext requestContext, final MethodParameter parameter) throws Throwable;

    @FunctionalInterface
    public interface SupportsFunction {

        boolean supports(MethodParameter parameter);
    }

}

类型层次结构

支持了众多参数类型:基本类型,cookies,文件上传,请求头以及自定义参数处理器,配置灵活,扩展性极强。

参数处理器优先级

这么多参数处理器,如果我想使自定义的参数处理器,但是默认的刚好也能处理该参数。怎么办呢?可配置参数处理器的优先级只要优先级大就会覆盖默认的。

使用接口设置优先级

内置了OrderedParameterResolver接口,其返回了默认优先级Ordered#LOWEST_PRECEDENCE, 重写Ordered#getOrder()方法就可以设置优先级。

public interface OrderedParameterResolver extends ParameterResolver, Ordered {

    @Override
    default int getOrder() {
        return LOWEST_PRECEDENCE;
    }
}

使用注解设置优先级

也可以在参数处理器类上添加@Order注解即可获得优先级功能。推荐使用注解的方式,因为更简单直白。

@Order(123)
public class PathVariableParameterResolver implements OrderedParameterResolver {

    @Override
    public boolean supports(final MethodParameter parameter) {
        return parameter.isAnnotationPresent(PathVariable.class);
    }
...

解析参数列表

核心方法HandlerMethod#resolveParameters(RequestContext)返回一个Object数组

public Object[] resolveParameters(final RequestContext requestContext) throws Throwable {
    // log.debug("set parameter start");
    final MethodParameter[] parameters = getParameters();
    if (parameters == MethodParameter.EMPTY_ARRAY) {
        return null;
    }
    final Object[] args = new Object[parameters.length];
    int i = 0;
    for (final MethodParameter parameter : parameters) {
        args[i++] = parameter.resolveParameter(requestContext);
    }
    return args;
}

调用处理器方法

使用反射?(老版本使用了反射)我不使用反射,十几天前(2019-10-19凌晨)刚开源了一个使用字节码生成调用方法的库。https://github.com/TAKETODAY/today-method-invoker

整个程序在运行时几乎没有反射操作所以我认为他是 😐 today-web is a servlet based high-performance lightweight web framework。

  • 老版本:
private final Method method;

public Object invokeHandler(final RequestContext request) throws Throwable {
    return method.invoke(getObject(), resolveParameters(request));
}
  • 新版本:
private final MethodInvoker handlerInvoker;

public Object invokeHandler(final RequestContext request) throws Throwable {
    return handlerInvoker.invoke(getObject(), resolveParameters(request));
}

未完

版权声明:本文为作者原创文章,转载时请务必声明出处并添加指向此页面的链接。
分享:
发表评论

目前您尚未登录,请 登录 后进行评论

评论信息