jfinal源码04:web之Interceptor

还记得我们第03节的Controller的初始化过程吗?

Jfinal类

1
2
3
4
5
6
7
8
private void initActionMapping() {
// 从配置文件获取路由 初始化actionMapping
this.actionMapping = new ActionMapping(Config.getRoutes());
// 把路由分别拆分成action映射(利用反射)。 这就完成了路径到controller方法的映射
// 这一步同时完成了action的初始化
this.actionMapping.buildActionMapping();
Config.getRoutes().clear();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
protected void buildActionMapping() {
this.mapping.clear();
Set<String> excludedMethodName = this.buildExcludedMethodName();
InterceptorManager interMan = InterceptorManager.me();
Iterator var3 = this.getRoutesList().iterator();

while(var3.hasNext()) {
Routes routes = (Routes)var3.next();
Iterator var5 = routes.getRouteItemList().iterator();

while(var5.hasNext()) {
Route route = (Route)var5.next();
Class<? extends Controller> controllerClass = route.getControllerClass();
Interceptor[] controllerInters = interMan.createControllerInterceptor(controllerClass);
boolean sonOfController = controllerClass.getSuperclass() == Controller.class;
Method[] methods = sonOfController ? controllerClass.getDeclaredMethods() : controllerClass.getMethods();
Method[] var11 = methods;
int var12 = methods.length;

for(int var13 = 0; var13 < var12; ++var13) {
Method method = var11[var13];
String methodName = method.getName();
if (!excludedMethodName.contains(methodName) && method.getParameterTypes().length == 0 && (!sonOfController || Modifier.isPublic(method.getModifiers()))) {
// 获取每一个action(方法的拦截器list)
Interceptor[] actionInters = interMan.buildControllerActionInterceptor(routes.getInterceptors(), controllerInters, controllerClass, method);
String controllerKey = route.getControllerKey();
ActionKey ak = (ActionKey)method.getAnnotation(ActionKey.class);
String actionKey;
if (ak != null) {
actionKey = ak.value().trim();
if ("".equals(actionKey)) {
throw new IllegalArgumentException(controllerClass.getName() + "." + methodName + "(): The argument of ActionKey can not be blank.");
}

if (!actionKey.startsWith("/")) {
actionKey = "/" + actionKey;
}
} else if (methodName.equals("index")) {
actionKey = controllerKey;
} else {
actionKey = controllerKey.equals("/") ? "/" + methodName : controllerKey + "/" + methodName;
}
// 初始化化了action,**这里就初始化了action上的interceptors数组**
Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, route.getFinalViewPath(routes.getBaseViewPath()));
if (this.mapping.put(actionKey, action) != null) {
throw new RuntimeException(this.buildMsg(actionKey, controllerClass, method));
}
}
}
}
}

this.routes.clear();
Action action = (Action)this.mapping.get("/");
if (action != null) {
this.mapping.put("", action);
}

}

具体看下Inteceptor init 流程

  • config file: me.add(new AuthInterceptor());默认添加全局拦截器
  • InterceptorManager 类里面维护globalActionInters数组
  • 初始化Action时会调用InterceptorManager类的doBuild(),此时全局的拦截器就绑定在action的interceptors数组里
  • ActionHandler类:(new Invocation(action, controller)).invoke();调用目标方法时就会按顺序调用 this.inters[this.index++].intercept(this);

总结一下:
Handler和Inteceptor区别?
Handler会拦截所有的web请求,是一个处理链的结构,链的结尾就是ActionHandler
全局Inteceptor绑定在每一个Controller中的每一个方法(action)上,每个action都会维护一个拦截器数据。会不会比较耗内存呢。
启示:
所以全局的操作最好定义handler,局部的操作定义inteceptor。减少对内存的消耗。
补充:(这里是否能这么做还是一个疑问,因为Handler会拦截所有的web请求,包括静态资源)。