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拦截,全县处理,日志记录等方面可以无侵入性的提供功能实现。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值