for (Method method : methods) {
String methodName = method.getName();
if (!excludedMethodName.contains(methodName) && method.getParameterTypes().length == 0) {
Interceptor[] methodInters = interceptorBuilder.buildMethodInterceptors(method);
Interceptor[] actionInters = interceptorBuilder.buildActionInterceptors(defaultInters, controllerInters, controllerClass, methodInters, method);
String controllerKey = entry.getKey();
ActionKey ak = method.getAnnotation(ActionKey.class);
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")) {
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);
}
}
}
2.if (!excludedMethodName.contains(methodName) && method.getParameterTypes().length == 0)
其实这句代码很简单, excludedMethodName是父类中的Controller无参数的方法,这里主要是获取我们自定义的方法入口
3.如果是我们定义的BlogController.java,这里就是让BlogController.java中的方法进入,而不让其父类的方法进入,例如下面的index(),add(),save(),edit(),delete()可以满足条件
public void index() {
setAttr("blogPage", Blog.dao.paginate(getParaToInt(0, 1), 10, "select *", "from blog order by id asc"));
render("blog.html");
}
public void add() {
}
@Before(BlogValidator.class)
public void save() {
getModel(Blog.class).save();
redirect("/blog");
}
public void edit() {
setAttr("blog", Blog.dao.findById(getParaToInt()));
}
@Before(BlogValidator.class)
public void update() {
getModel(Blog.class).update();
redirect("/blog");
}
public void delete() {
Blog.dao.deleteById(getParaToInt());
redirect("/blog");
}
3.假如进入的是save()方法,
Interceptor[] methodInters = interceptorBuilder.buildMethodInterceptors(method);
/**
* Build interceptors of Method
*/
Interceptor[] buildMethodInterceptors(Method method) {
Before before = method.getAnnotation(Before.class);
return before != null ? createInterceptors(before) : NULL_INTERCEPTOR_ARRAY;
}
/**
* Create interceptors with Annotation of Before. Singleton version.
*/
private Interceptor[] createInterceptors(Before beforeAnnotation) {
Interceptor[] result = null;
@SuppressWarnings("unchecked")
Class<Interceptor>[] interceptorClasses = (Class<Interceptor>[]) beforeAnnotation.value();
if (interceptorClasses != null && interceptorClasses.length > 0) {
result = new Interceptor[interceptorClasses.length];
for (int i=0; i<result.length; i++) {
result[i] = intersMap.get(interceptorClasses[i]);
if (result[i] != null)
continue;
try {
result[i] = (Interceptor)interceptorClasses[i].newInstance();
intersMap.put(interceptorClasses[i], result[i]);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
return result;
}
methodInters相当于获取BlogValidator接口,validate验证这块,我后面会详细介绍其原理,现在就不要深究啦@Before(BlogValidator.class)
public void save() {
getModel(Blog.class).save();
redirect("/blog");
}
4.Interceptor[] actionInters = interceptorBuilder.buildActionInterceptors(defaultInters, controllerInters, controllerClass, methodInters, method);
该方法就是讲Global和Controller和Method上面的拦截器信息,如果有collerClearType,去除相应的拦截器,最后整合在一起 放入到actionInters中
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;
}
}
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;
}
5.String controllerKey = entry.getKey();在我们的例子中为=/blog
ActionKey ak = method.getAnnotation(ActionKey.class); 我们这里没有用到目前,不管他,很简单,自己看看就能明白啦
actonInters就是上面所说的拦截器
Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, routes.getViewPath(controllerKey));
mapping.put(actionKey, action);
routes.getViewPath(controllerKey)的值为= /blog/,actonInters就是上面所说的拦截器
如果是save方法:
controllerKey = /blog ,actionKey = /blog/save,controllerClass = BlogController.class,methodName = save,
controllerKey=/blog,actionKey=/blog,controllerClass=BlogController.class,methodName =index
同理如果是add()方法:
controllerKey=/blog,actionKey=/blog/add,controllerClass=BlogController.class,methodName=add
同理如果是edit()方法:
controllerKey=/blog,actionKey=/blog/edit,controllerClass= BlogController.class,methodName=edit
同理如果是update()方法:
controllerKey=/blog,actionKey=/blog/update,controllerClass= BlogController.class,methodName=update
同理如果是delete()方法:
controllerKey=/blog,actionKey=/blog/delete,controllerClass= BlogController.class,methodName=delete
6. String controllerKey =entry.getKey();还有在我们中的例子为CommonController中的/
只有1个index方法
controllcontrollerKey=/,actionKey=/,controllerClass=CommonController.class,methodName =index
最后一个注意的地方,看看就明白啦
Action actoin = mapping.get("/");
if (actoin != null)
mapping.put("", actoin);