JFinal源码解析--ActionMapping,Interceptor

1. JFinal类 初始化ActionMapping

private void initActionMapping() {
        actionMapping = new ActionMapping(Config.getRoutes(), Config.getInterceptors());//将配置路径映射、拦截器,传给ActionMapping类
        actionMapping.buildActionMapping();//建立ActionMapping映射
    }

2. ActionMapping类

目的:得到请求URL与请求执行者Action的映射关系,保存到map中

Action中保存有拦截器,执行请求所需要的Controller类及方法,返回页面的目录等信息

Interceptor[]

  • 从配置里得到global级别拦截器

  • 从controller的注释声明(@before)得到controller级别拦截器

  • 依靠反射的方法遍历controller的方法,从方法的注释声明(@before)得到method级别拦截器

URL:ActionKey+Methodkey

  • 从配置里得到ActionKey

  • 从method上的注释声明得到ActionKey,没有声明的默认为method名

new 一个Action保存interceptor[],controller,method等信息

将URL,Action添加到map里保存,得到映射关系    map.add(URL,Action)

void buildActionMapping() {
        mapping.clear();
        Set<String> excludedMethodName = buildExcludedMethodName();//得到Controller类(父类)里的无参方法
        InterceptorBuilder interceptorBuilder = new InterceptorBuilder();//拦截器创建类(保存拦截器)
        Interceptor[] defaultInters = interceptors.getInterceptorArray();//在config类里我们配置的全局拦截器
        interceptorBuilder.addToInterceptorsMap(defaultInters);//把全局拦截器添加到map里保存
        for (Entry<String, Class<? extends Controller>> entry : routes.getEntrySet()) {//遍历config类里我们配置的请求-Controller映射 add("/", ManagerController.class);
            Class<? extends Controller> controllerClass = entry.getValue();//得到控制器Controller类
            Interceptor[] controllerInters = interceptorBuilder.buildControllerInterceptors(controllerClass);//得到控制器上的拦截器
            Method[] methods = controllerClass.getMethods();//得到控制器的所有方法
            for (Method method : methods) {
                String methodName = method.getName();
                if (!excludedMethodName.contains(methodName) && method.getParameterTypes().length == 0) {//我们写的控制器都继承了Controller父类,同时添加了自己的无参方法,这里的目的就是得到我们自己添加的方法(controller的所有无参方法除去父类里的无参方法,就是我们自己添加的方法了)。

                    Interceptor[] methodInters = interceptorBuilder.buildMethodInterceptors(method);//得到method上的拦截器
                    Interceptor[] actionInters = interceptorBuilder.buildActionInterceptors(defaultInters, controllerInters, controllerClass, methodInters, method);//将拦截器按照优先级(global>controller>method)依次保存到actionInters
                    String controllerKey = entry.getKey();
                    
                    ActionKey ak = method.getAnnotation(ActionKey.class);//得到该方法上添加的ActionKey声明(即请求路径)
                    if (ak != null) {//有声明则ActionKey为声明的值,如果没有声明则ActionKey默认为该方法名,默认index的ActionKey为“/”值,将请求URL(controllerKey+ActionKey)做为key,Action作为value保存到mapping中。Action中保存有拦截器,执行请求所需要的Controller类及方法,返回页面的目录等信息
                        String actionKey = ak.value().trim();
                        if ("".equals(actionKey))
                            throw new IllegalArgumentException(controllerClass.getName() + "." + methodName + "(): The argument of ActionKey can not be blank.");
                        
                        if (!actionKey.startsWith(SLASH))
                            actionKey = SLASH + actionKey;
                        
                        if (mapping.containsKey(actionKey)) {
                            warnning(actionKey, controllerClass, method);
                            continue;
                        }
                        
                        Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, routes.getViewPath(controllerKey));
                        mapping.put(actionKey, action);
                    }
                    else if (methodName.equals("index")) {
                        String actionKey = controllerKey;
                        
                        Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, routes.getViewPath(controllerKey));
                        action = mapping.put(actionKey, action);
                        
                        if (action != null) {
                            warnning(action.getActionKey(), action.getControllerClass(), action.getMethod());
                        }
                    }
                    else {
                        String actionKey = controllerKey.equals(SLASH) ? SLASH + methodName : controllerKey + SLASH + methodName;
                        
                        if (mapping.containsKey(actionKey)) {
                            warnning(actionKey, controllerClass, method);
                            continue;
                        }
                        
                        Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, routes.getViewPath(controllerKey));
                        mapping.put(actionKey, action);
                    }
                }
            }
        }
        
        // support url = controllerKey + urlParas with "/" of controllerKey
        Action actoin = mapping.get("/");
        if (actoin != null)
            mapping.put("", actoin);
    }

private Set<String> buildExcludedMethodName() {//返回Controller类里的无参方法
        Set<String> excludedMethodName = new HashSet<String>();
        Method[] methods = Controller.class.getMethods();
        for (Method m : methods) {
            if (m.getParameterTypes().length == 0)//getParameterTypes获取该方法的参数数组,这里是得到controller的无参方法
                excludedMethodName.add(m.getName());
        }
        return excludedMethodName;
    }

3. InterceptorBuilder 拦截器创建类

@SuppressWarnings("unchecked")
    void addToInterceptorsMap(Interceptor[] defaultInters) {
        for (Interceptor inter : defaultInters)
            intersMap.put((Class<Interceptor>)inter.getClass(), inter);
    }

/**
     * Build interceptors of Action
     * 将拦截器按照优先级(global>controller>method)依次保存到actionInters
     */
    Interceptor[] buildActionInterceptors(Interceptor[] defaultInters, Interceptor[] controllerInters, Class<? extends Controller> controllerClass, Interceptor[] methodInters, Method method) {
        ClearLayer controllerClearType = getControllerClearType(controllerClass);
        if (controllerClearType != null) {
            defaultInters = NULL_INTERCEPTOR_ARRAY;
        }
        
        ClearLayer methodClearType = getMethodClearType(method);
        if (methodClearType != null) {
            controllerInters = NULL_INTERCEPTOR_ARRAY;
            if (methodClearType == ClearLayer.ALL) {
                defaultInters = NULL_INTERCEPTOR_ARRAY;
            }
        }
        
        int size = defaultInters.length + controllerInters.length + methodInters.length;
        Interceptor[] result = (size == 0 ? NULL_INTERCEPTOR_ARRAY : new Interceptor[size]);
        
        int index = 0;
        for (int i=0; i<defaultInters.length; i++) {
            result[index++] = defaultInters[i];
        }
        for (int i=0; i<controllerInters.length; i++) {
            result[index++] = controllerInters[i];
        }
        for (int i=0; i<methodInters.length; i++) {
            result[index++] = methodInters[i];
        }
        
        return result;
    }




转载于:https://my.oschina.net/u/1182234/blog/265136

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值