美文网首页
jfinal源码04:web之Interceptor

jfinal源码04:web之Interceptor

作者: 城南码农 | 来源:发表于2017-12-17 15:33 被阅读0次

还记得我们第03节的Controller的初始化过程吗?
Jfinal类

private void initActionMapping() {
// 从配置文件获取路由  初始化actionMapping
        this.actionMapping = new ActionMapping(Config.getRoutes());
//  把路由分别拆分成action映射(利用反射)。 这就完成了路径到controller方法的映射
// 这一步同时完成了action的初始化
        this.actionMapping.buildActionMapping();
        Config.getRoutes().clear();
    }
protected void buildActionMapping() {
        this.mapping.clear();
        Set<String> excludedMethodName = this.buildExcludedMethodName();
        InterceptorManager interMan = InterceptorManager.me();
        Iterator var3 = this.getRoutesList().iterator();

        while(var3.hasNext()) {
            Routes routes = (Routes)var3.next();
            Iterator var5 = routes.getRouteItemList().iterator();

            while(var5.hasNext()) {
                Route route = (Route)var5.next();
                Class<? extends Controller> controllerClass = route.getControllerClass();
                Interceptor[] controllerInters = interMan.createControllerInterceptor(controllerClass);
                boolean sonOfController = controllerClass.getSuperclass() == Controller.class;
                Method[] methods = sonOfController ? controllerClass.getDeclaredMethods() : controllerClass.getMethods();
                Method[] var11 = methods;
                int var12 = methods.length;

                for(int var13 = 0; var13 < var12; ++var13) {
                    Method method = var11[var13];
                    String methodName = method.getName();
                    if (!excludedMethodName.contains(methodName) && method.getParameterTypes().length == 0 && (!sonOfController || Modifier.isPublic(method.getModifiers()))) {
                  // 获取每一个action(方法的拦截器list)
                        Interceptor[] actionInters = interMan.buildControllerActionInterceptor(routes.getInterceptors(), controllerInters, controllerClass, method);
                        String controllerKey = route.getControllerKey();
                        ActionKey ak = (ActionKey)method.getAnnotation(ActionKey.class);
                        String actionKey;
                        if (ak != null) {
                            actionKey = ak.value().trim();
                            if ("".equals(actionKey)) {
                                throw new IllegalArgumentException(controllerClass.getName() + "." + methodName + "(): The argument of ActionKey can not be blank.");
                            }

                            if (!actionKey.startsWith("/")) {
                                actionKey = "/" + actionKey;
                            }
                        } else if (methodName.equals("index")) {
                            actionKey = controllerKey;
                        } else {
                            actionKey = controllerKey.equals("/") ? "/" + methodName : controllerKey + "/" + methodName;
                        }
      // 初始化化了action,**这里就初始化了action上的interceptors数组**
                        Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, route.getFinalViewPath(routes.getBaseViewPath()));
                        if (this.mapping.put(actionKey, action) != null) {
                            throw new RuntimeException(this.buildMsg(actionKey, controllerClass, method));
                        }
                    }
                }
            }
        }

        this.routes.clear();
        Action action = (Action)this.mapping.get("/");
        if (action != null) {
            this.mapping.put("", action);
        }

    }

具体看下Inteceptor init 流程

  • config file: me.add(new AuthInterceptor());默认添加全局拦截器
  • InterceptorManager 类里面维护globalActionInters数组
  • 初始化Action时会调用InterceptorManager类的doBuild(),此时全局的拦截器就绑定在action的interceptors数组里
  • ActionHandler类:(new Invocation(action, controller)).invoke();调用目标方法时就会按顺序调用 this.inters[this.index++].intercept(this);

总结一下:
Handler和Inteceptor区别?
Handler会拦截所有的web请求,是一个处理链的结构,链的结尾就是ActionHandler
全局Inteceptor绑定在每一个Controller中的每一个方法(action)上,每个action都会维护一个拦截器数据。会不会比较耗内存呢。
启示:
所以全局的操作最好定义handler,局部的操作定义inteceptor。减少对内存的消耗。
补充:(这里是否能这么做还是一个疑问,因为Handler会拦截所有的web请求,包括静态资源)。

相关文章

网友评论

      本文标题:jfinal源码04:web之Interceptor

      本文链接:https://www.haomeiwen.com/subject/mbaewxtx.html