1、首先介绍下JFinal中AOP的主角Interceptor接口:
public interface Interceptor {
void intercept(Invocation inv);
}
在源码中已经有了多种功能的实现,如Validator(校验功能)、Tx(事务功能),因此我们可以根据实际的需求来实现该接口就可以了。
2、用户需要实现一个继承JFinalConfig的配置类,实现void configInterceptor(Interceptors me)该方法来导入全局的Interceptor
public class MyJFinalApp extends JFinalConfig {
@Override
public void configConstant(Constants arg0) {
arg0.setDevMode(true);
arg0.setEncoding("utf-8");
arg0.setViewType(ViewType.JSP);
}
@Override
public void configHandler(Handlers arg0) {
arg0.add(new ContextPathHandler("basePath"));
}
@Override
public void configInterceptor(Interceptors arg0) {
arg0.add(new LogInterceptor()); //添加全局拦截器
}
@Override
public void configPlugin(Plugins arg0) {
// TODO Auto-generated method stub
}
@Override
public void configRoute(Routes arg0) {
arg0.add("/", IndexControllerJFinal.class);
}
3、在JFinal类初始化时会调用initActionMapping()方法
public final class JFinal {
private Constants constants;
private ActionMapping actionMapping;
private Handler handler;
private ServletContext servletContext;
private String contextPath = "";
private static IServer server;
private static final JFinal me = new JFinal();
private JFinal() {
}
public static JFinal me() {
return me;
}
boolean init(JFinalConfig jfinalConfig, ServletContext servletContext) {
this.servletContext = servletContext;
this.contextPath = servletContext.getContextPath();
initPathUtil();
Config.configJFinal(jfinalConfig); // start plugin and init log factory in this method
constants = Config.getConstants();
initActionMapping();
initHandler();
initRender();
initOreillyCos();
initTokenManager();
return true;
}
.
.
.
}
4、在initActionMapping方法中调用actionMapping.buildActionMapping()方法。
private void initActionMapping() {
actionMapping = new ActionMapping(Config.getRoutes(), Config.getInterceptors());
actionMapping.buildActionMapping();
}
5、关键代码就是这个buildActionMapping()方法:
void buildActionMapping() {
mapping.clear();
Set<String> excludedMethodName = buildExcludedMethodName();
InterceptorManager interMan = InterceptorManager.me();
for (Entry<String, Class<? extends Controller>> entry : routes.getEntrySet()) {
Class<? extends Controller> controllerClass = entry.getValue();
Interceptor[] controllerInters = interMan.createControllerInterceptor(controllerClass); //创建每个类(controller)的拦截器
boolean sonOfController = (controllerClass.getSuperclass() == Controller.class);
Method[] methods = (sonOfController ? controllerClass.getDeclaredMethods() : controllerClass.getMethods());
for (Method method : methods) {
String methodName = method.getName();
if (excludedMethodName.contains(methodName) || method.getParameterTypes().length != 0)
continue ;
if (sonOfController && !Modifier.isPublic(method.getModifiers()))
continue ;
Interceptor[] actionInters = interMan.buildControllerActionInterceptor(controllerInters, controllerClass, method); //创建每个action的对应拦截器
String controllerKey = entry.getKey();
ActionKey ak = 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(SLASH))
actionKey = SLASH + actionKey;
}
else if (methodName.equals("index")) {
actionKey = controllerKey;
}
else {
actionKey = controllerKey.equals(SLASH) ? SLASH + methodName : controllerKey + SLASH + methodName;
}
Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, routes.getViewPath(controllerKey));
if (mapping.put(actionKey, action) != null)
throw new RuntimeException(buildMsg(actionKey, controllerClass, method));
}
}
// support url = controllerKey + urlParas with "/" of controllerKey
Action action = mapping.get("/");
if (action != null)
mapping.put("", action);
}
1)首先调用InterceptorManager类中createControllerInterceptor()方法,来创建每个controller的Interceptors(通过@Before)。createControllerInterceptor方法最终会调用createInterceptor方法
public Interceptor[] createControllerInterceptor(Class<? extends Controller> controllerClass) {
//通过注解来获取对应controller的class基本的拦截器
return createInterceptor(controllerClass.getAnnotation(Before.class));
}
public Interceptor[] createInterceptor(Class<? extends Interceptor>[] interceptorClasses) {
if (interceptorClasses == null || interceptorClasses.length == 0) {
return NULL_INTERS;
}
Interceptor[] result = new Interceptor[interceptorClasses.length];
try {
for (int i=0; i<result.length; i++) {
result[i] = singletonMap.get(interceptorClasses[i]);
if (result[i] == null) {
result[i] = (Interceptor)interceptorClasses[i].newInstance();
singletonMap.put(interceptorClasses[i], result[i]);
}
}
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
2)获取每个controller中的action方法,再创建每个方法的Interceptors,并通过@Clear注解去掉需要忽略的Interceptors。
6、最终把每个action的所有Interceptors通过Action类的构造函数传入Action对象中(buildActionMapping方法中)。