Jfinal学习笔记

实习期间,公司使用jfinal做开发,所以就学习了这个框架

Jfinal作为一个极速ORM,使用上非常方便,核心源代码1万多行,压缩后只有200KB。

 

从入口开始

作为一个web项目,首先解读web.xml文件,其中配置了一个filter

 

<filter-class>com.jfinal.core.JFinalFilter</filter-class>

 

finalfilter继承了filter

关于filkterfilterjsp中的一个接口,需要实现的方法有Init(),doFilter(),destroy()三个必要的方法。

打开源代码中的JfinalFilter往下解读进入public void init(FilterConfig filterConfig) ,createJFinalConfig函数作用是初始化jfinalConfig,它使用了java反射方式查找,使用class.newInstance()方法实例化一个对象,再将temp对象强制转化成JFinalConfig对象

初始化完成jfinalConfig之后,使用了jfinal.init(jfinalConfig, filterConfig.getServletContext())这一方法。

再次进入JFinal

 

public final class JFinal{
  .............
  boolean init(JFinalConfig jfinalConfig, ServletContext servletContext) {
          this.servletContext = servletContext;
          this.contextPath = servletContext.getContextPath();
          initPathUtil();//获得webroot路径    
          Config.configJFinal(jfinalConfig);    // start plugin and init logger factory in this method
          constants = Config.getConstants();    
          initActionMapping();
          initHandler();
          initRender();
          initActiveRecord();
          initOreillyCos();
          initI18n();
          initTokenManager();    
          return true;
      }
}

 

Config.configJFinal(jfinalConfig);方法为Config类中的几个静态变量赋值,并启动插件

initActionMapping();initHandler();initRender();initActiveRecord();initOreillyCos();initI18n();initTokenManager();依次做了初始化工作。

private void initActionMapping() {
        actionMapping = new ActionMapping(Config.getRoutes(), Config.getInterceptors());   //传入了jfinalconfig中的routs和Interceptors,jfinalConfig中的Interceptors为全局拦截器
        actionMapping.buildActionMapping();
    }

initActionMapping是jfinal中核心设计,代码比较长

 

private final Map<String, Action> mapping = new HashMap<String, Action>();

void
buildActionMapping() { mapping.clear(); Set<String> excludedMethodName = buildExcludedMethodName(); //获得Controller自带的一些方法名称 InterceptorBuilder interceptorBuilder = new InterceptorBuilder(); Interceptor[] defaultInters = interceptors.getInterceptorArray(); interceptorBuilder.addToInterceptorsMap(defaultInters); for (Entry<String, Class<? extends Controller>> entry : routes.getEntrySet()) {//循环遍历routs Class<? extends Controller> controllerClass = entry.getValue(); Interceptor[] controllerInters = interceptorBuilder.buildControllerInterceptors(controllerClass); //在buildControllerInterceptors方法中,如果有Before声明 Method[] methods = controllerClass.getMethods(); //获取controllerClass所有方法 for (Method method : methods) { String methodName = method.getName(); if (!excludedMethodName.contains(methodName) && method.getParameterTypes().length == 0) { //无参数函数为action,且不是基类Controller.class包含的方法 Interceptor[] methodInters = interceptorBuilder.buildMethodInterceptors(method);//在此方法中 查找Before Interceptor[] actionInters = interceptorBuilder.buildActionInterceptors(defaultInters, controllerInters, controllerClass, methodInters, method);//返回整个action的拦截器[Interceptor] String controllerKey = entry.getKey(); //controllerKey即为path路径 ActionKey ak = method.getAnnotation(ActionKey.class);//获得注解actionkey if (ak != null) { 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")) {//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); }

 

buildExcludedMethodName()首先将Controllerlei中的无参函数取出,放入set集合中
private Set<String> buildExcludedMethodName() {
        Set<String> excludedMethodName = new HashSet<String>();
        Method[] methods = Controller.class.getMethods();
        for (Method m : methods) {
            if (m.getParameterTypes().length == 0)
                excludedMethodName.add(m.getName());
        }
        return excludedMethodName;
    }
    

Interceptor[] defaultInters = interceptors.getInterceptorArray();获得全局拦截器,转换成数组后的GlobalInterceptor

 

然后for循环遍历routs

循环中

Interceptor[] controllerInters = interceptorBuilder.buildControllerInterceptors(controllerClass); 返回controller中的Before声明

    Interceptor[] buildControllerInterceptors(Class<? extends Controller> controllerClass) {
        Before before = controllerClass.getAnnotation(Before.class);
        return before != null ? createInterceptors(before) : NULL_INTERCEPTOR_ARRAY;
    }

在循环routs中嵌套循环遍历每一个函数方法

这里就知道了为什么Controller中的无参函数才是一个action

if (!excludedMethodName.contains(methodName) && method.getParameterTypes().length == 0) {
//controller中的无参,并且不是基类Controller的方法
..............................
}

 返回的每一个controller中无参的方法即为一个action

Interceptor[] methodInters = interceptorBuilder.buildMethodInterceptors(method);
Interceptor[] actionInters = interceptorBuilder.buildActionInterceptors(defaultInters, controllerInters, controllerClass, methodInters, method);
                    

构建action的所有拦截器,interceptorBuilder.buildActionInterceptors(defaultInters, controllerInters, controllerClass, methodInters, method);中勿个参数就分别对应了全局拦截器,controller拦截器,controller类,action声明的before拦截器和方法体。

 

action的生成遵循几个规则:

    1、如果声明了actionkey注解,就根据actionkey中的声明。

    2、若方法名是index(),则action就于controllerkey。

    3、否则actionkey等于 controllerkey+“/”+methodName

 

 

 

 

 

 

 

 

posted @ 2013-08-23 12:05  fanhualuodi  阅读(1238)  评论(0编辑  收藏  举报