Jfinal学习笔记
实习期间,公司使用jfinal做开发,所以就学习了这个框架
Jfinal作为一个极速ORM,使用上非常方便,核心源代码1万多行,压缩后只有200多KB。
从入口开始
作为一个web项目,首先解读web.xml文件,其中配置了一个filter,
<filter-class>com.jfinal.core.JFinalFilter</filter-class>
finalfilter继承了filter。
关于filkter:filter是jsp中的一个接口,需要实现的方法有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
Jfinal学习笔记的更多相关文章
- JFinal 学习笔记之Handler包分析
HandlerFactory.java HandlerFactory是不可实例化的,因为 它的构造 函数 特意定位 私有 的:它有一个 静态的方法叫做 getHandler,它有两个参数 ,一个是Ha ...
- jfinal框架教程-学习笔记
jfinal框架教程-学习笔记 JFinal 是基于 Java 语言的极速 WEB + ORM 开发框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restfu ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
- CSS学习笔记
CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...
随机推荐
- Javascript手记-垃圾收集
如果有人问.net的垃圾回收,大家会马上想到gc,那如果有人问你javascript如何进行内存管理的呢?挠挠头,一口香瓜,听我细细道来! javascript具有自动垃圾收集机制,执行环境会负责管理 ...
- trate
from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extraction.text imp ...
- HDU4861:Couple doubi(费马小定理)
题意: 给出k个球和质数p,对每个球以公式val(i)=1^i+2^i+...+(p-1)^i (mod p)计算出它的价值,然后两个人轮流拿,最后拿到的球的总价值大的获胜,问我们先手是否获胜. 我们 ...
- USACO 2013 November Contest Gold 简要题解
Problem 1. Empty Stalls 扫两遍即可. Problem 2. Line of Sight 我们发现能互相看见的一对点一定能同时看见粮仓的某一段.于是转换成有n段线段,问有多少对线 ...
- Calculating a bearing between points in location-aware apps
https://software.intel.com/en-us/blogs/2012/11/30/calculating-a-bearing-between-points-in-location-a ...
- JNI调用测试
有需求使用JNI调用,籍着这个机会按照<Linux下测试Java的JNI(Java Native Interface)>上进行了下测试. 这篇文章记录得很清楚了,对原理未做深入的分析,希望 ...
- ocp 1Z0-047 1-60题解析
1. You need to load information about new customers from the NEW_CUST table into the tables CUST and ...
- iOS 8版本信息与屏幕尺寸
原文 http://www.cnblogs.com/smileEvday/p/iOS8.html 1.UIWindow的bounds iOS 7之前Window的bounds不会随着方向而变化, ...
- 对于一个网站,如何禁止直接从浏览器Web browser中访问js文件
比如有一个网站,https://testsystem.infotest.com 在这个网站的内容文件目录下面,有一个scripts文件夹,该文件夹中有一个js文件,比如lukeTest.js文件 这样 ...
- POJ1179Polygon(DP)
Polygon Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4456 Accepted: 1856 Descripti ...