JFianl源码走读_7_Interceptor

JFinal中的aop

jfinal中的aop具体实现就是interceptor

Interceptor初始化

Interceptor的初始化是和actionMapping耦合在一起

Interceptor的创建和全局拦截器的初始化

// 实例化interceptorBuilder ,构造方法无操作 InterceptorBuilder interceptorBuilder = new InterceptorBuilder(); // 将list转为array Interceptor[] defaultInters = interceptors.getInterceptorArray(); // 将全局拦截器添加到interceptorBuilder私有的拦截器Map中 interceptorBuilder.addToInterceptorsMap(defaultInters);

controller级别的拦截器的初始化

// 创建当前Controller的拦截器,处理@before注解 Interceptor[] controllerInters = interceptorBuilder
                    .buildControllerInterceptors(controllerClass);

method级别的拦截器的初始化

// 创建当前Method的拦截器,处理@before注解 Interceptor[] methodInters = interceptorBuilder
                            .buildMethodInterceptors(method);

action的拦截器构建

// 创建此method对应的action的拦截器,此拦截器由全局、controller、method级别的拦截器依次拦截组成的拦截器栈 Interceptor[] actionInters = interceptorBuilder
                            .buildActionInterceptors(defaultInters,
                                    controllerInters, controllerClass,
                                    methodInters, method);

依次探究buildControllerInterceptors, buildMethodInterceptors, buildActionInterceptors方法的具体实现

/** * Build interceptors of Controller */ Interceptor[] buildControllerInterceptors(Class<? extends Controller> controllerClass) { // 获取controller类的@before注解 Before before = controllerClass.getAnnotation(Before.class); // 如果注解不为空,那么创建这个注解对应的拦截器,createInterceptors方法延后分析,否则返回 new Interceptor[0],即NULL_INTERCEPTOR_ARRAY; return before != null ? createInterceptors(before) : NULL_INTERCEPTOR_ARRAY;
    }
/** * Build interceptors of Method */ Interceptor[] buildMethodInterceptors(Method method) { // 获取method的@before注解 Before before = method.getAnnotation(Before.class); // 如果注解不为空,那么创建这个注解对应的拦截器,createInterceptors方法延后分析,否则返回 new Interceptor[0],即NULL_INTERCEPTOR_ARRAY; return before != null ? createInterceptors(before) : NULL_INTERCEPTOR_ARRAY;
    }
/** * Build interceptors of Action */ 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;
            }
        } // 按照全局,controller,method级别依次添加到action的拦截器栈中 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;
    }
createInterceptors(before)方法解析
@Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface Before { Class<? extends Interceptor>[] value();
}

Before注解的定义,表明before注解是支持同时配置多个interceptor的

private Interceptor[] createInterceptors(Before beforeAnnotation) {
        Interceptor[] result = null; @SuppressWarnings("unchecked") // 获取参数中拦截器的Class Class<Interceptor>[] interceptorClasses = (Class<Interceptor>[]) beforeAnnotation.value(); if (interceptorClasses != null && interceptorClasses.length > 0) { // 创建interceptor承载数组 result = new Interceptor[interceptorClasses.length]; for (int i=0; i<result.length; i++) { // 保证每个拦截器的实例只有一个,如果拦截器缓存中有目标拦截器,就直接取出 result[i] = intersMap.get(interceptorClasses[i]); if (result[i] != null) continue; // 新建拦截器,并添加到缓存Map中 try {
                    result[i] = (Interceptor)interceptorClasses[i].newInstance();
                    intersMap.put(interceptorClasses[i], result[i]);
                } catch (Exception e) { throw new RuntimeException(e);
                }
            }
        } return result;
    }

由创建interceptor实例可知,实际上特定interceptor在jfinal app中实际上只有一个,此举可有效解决为每个action配置拦截器时新建interceptor的资源消耗,但同时不免有线程安全问题

getControllerClearType(controllerClass), getMethodClearType(method);分析
private ClearLayer getMethodClearType(Method method) { // 处理ClearInterceptor注解 ClearInterceptor clearInterceptor = method.getAnnotation(ClearInterceptor.class); // 如果clearInterceptor!=null,则取到注解中传递的value return clearInterceptor != null ? clearInterceptor.value() : null ;
    } private ClearLayer getControllerClearType(Class<? extends Controller> controllerClass) { // 处理ClearInterceptor注解 ClearInterceptor clearInterceptor = controllerClass.getAnnotation(ClearInterceptor.class); // 如果clearInterceptor!=null,则取到注解中传递的value return clearInterceptor != null ? clearInterceptor.value() : null ;
    }
@Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface ClearInterceptor { ClearLayer value() default ClearLayer.UPPER;
}
public enum ClearLayer { /** * clear the interceptor of upper layer */ UPPER, /** * clear the interceptor of all layers */ ALL;
}

可能某些action不需要在其上层的controller、全局级别的拦截,此时,作者引入了清理某个级别拦截器的注解,可以方便的清理某个action上的某个层次的拦截器,但同时如果开发者只是希望移除某个级别之上的某个拦截器,则比较难以处理,按照jfinal的处理逻辑,只能先移除某个级别的所有拦截器,然后再添加需要的拦截器,不免有些麻烦,不知作者后期是否会对这种情况提供支持。

interceptor运行时

在jfinal的运行时中已经分析过了

小结

解读JFinal中的interceptor组件的实现,servlet规范中的filter,struts2中的拦截器,以及springmvc中的拦截器,这些都说明在web开发中拦截器的不可缺少性,在url拦截,全县处理,日志记录等方面可以无侵入性的提供功能实现。

你可能感兴趣的:(AOP,Interceptor,源码分析,jFinal,javawe)