您的位置:首页 > 其它

JFinal 源码解析系列二

2015-07-16 18:45 387 查看
1 当访问某个链接之后JFinal便会调用doFilter()进行处理。

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
request.setCharacterEncoding(encoding);//设置编码
String target = request.getRequestURI();//获取URI如访问 /app/login
if (contextPathLength != 0)
target = target.substring(contextPathLength);//去除weapp name
boolean[] isHandled = {false};//是否处理标识符
try {
handler.handle(target, request, response, isHandled);//处理请求,之后进行详细解析
}
catch (Exception e) {
if (log.isErrorEnabled()) {
String qs = request.getQueryString();
log.error(qs == null ? target : target + "?" + qs, e);
}
}
if (isHandled[0] == false)
chain.doFilter(request, response);//继续处理chain上其他操作
}

handler.handle(target, request, response, isHandled);

handler中的方法handle方法为抽象方法,由于为加载其他插件,先分析ActionHandler中的handle方法

final class ActionHandler extends Handler {

private final boolean devMode;
private final ActionMapping actionMapping;
private static final RenderFactory renderFactory = RenderFactory.me();
private static final Logger log = Logger.getLogger(ActionHandler.class);

public ActionHandler(ActionMapping actionMapping, Constants constants) {
this.actionMapping = actionMapping;
this.devMode = constants.getDevMode();
}

/**
* handle
* 1: Action action = actionMapping.getAction(target)
* 2: new Invocation(...).invoke()
* 3: render(...)
*/
public final void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
if (target.indexOf('.') != -1) {//urk中存在.则跳过
return ;
}

isHandled[0] = true;//标识为true
String[] urlPara = {null};//url参数数组
Action action = actionMapping.getAction(target, urlPara);//从actionMAp中获取处理的action对象

if (action == null) {//为空则返回404
if (log.isWarnEnabled()) {
String qs = request.getQueryString();
log.warn("404 Action Not Found: " + (qs == null ? target : target + "?" + qs));
}
renderFactory.getErrorRender(404).setContext(request, response).render();
return ;
}

try {
Controller controller = action.getControllerClass().newInstance();//获取action的具体Controller的名字并实例化,高并发和访问估计会带来问题
controller.init(request, response, urlPara[0]);//初始化request,response,以及url参数

if (devMode) {
boolean isMultipartRequest = ActionReporter.reportCommonRequest(controller, action);//判断是否需要打印相关信息到控制台
new Invocation(action, controller).invoke();//调用invoke方法进行处理,此为核心代码。
if (isMultipartRequest) ActionReporter.reportMultipartRequest(controller, action);
}
else {
new Invocation(action, controller).invoke();
}

Render render = controller.getRender();//get the render
if (render instanceof ActionRender) {
String actionUrl = ((ActionRender)render).getActionUrl();//获取actionURl
if (target.equals(actionUrl))
throw new RuntimeException("The forward action url is the same as before.");
else
handle(actionUrl, request, response, isHandled);
return ;
}
//不涉及渲染的操作render为null
if (render == null)
render = renderFactory.getDefaultRender(action.getViewPath() + action.getMethodName());
render.setContext(request, response, action.getViewPath()).render();
}
catch (RenderException e) {
if (log.isErrorEnabled()) {
String qs = request.getQueryString();
log.error(qs == null ? target : target + "?" + qs, e);
}
}
catch (ActionException e) {
int errorCode = e.getErrorCode();
if (errorCode == 404 && log.isWarnEnabled()) {
String qs = request.getQueryString();
log.warn("404 Not Found: " + (qs == null ? target : target + "?" + qs));
}
else if (errorCode == 401 && log.isWarnEnabled()) {
String qs = request.getQueryString();
log.warn("401 Unauthorized: " + (qs == null ? target : target + "?" + qs));
}
else if (errorCode == 403 && log.isWarnEnabled()) {
String qs = request.getQueryString();
log.warn("403 Forbidden: " + (qs == null ? target : target + "?" + qs));
}
else if (log.isErrorEnabled()) {
String qs = request.getQueryString();
log.error(qs == null ? target : target + "?" + qs, e);
}
e.getErrorRender().setContext(request, response, action.getViewPath()).render();
}
catch (Throwable t) {
if (log.isErrorEnabled()) {
String qs = request.getQueryString();
log.error(qs == null ? target : target + "?" + qs, t);
}
renderFactory.getErrorRender(500).setContext(request, response, action.getViewPath()).render();
}
}
}

以下为核心处理代码

new Invocation(action, controller).invoke();

public void invoke() {
// inters为此action的拦截器栈,依次执行此action的拦截器,由初始化过程可知,拦截器顺序依次为 全局,controller,method
//此方法是个递归方法 拦截器01_before->拦截器02_before->xx_before->action.getMethod.invoke(controller,NULL_ARGS)->xx_after->拦截器02_after->拦截器01_after
//作者原话:inters是一个拦截器数组,index变量是指向这个数组当前正在执行的拦截器的下标。ActionInvocation.invoke()方法是一个递归调用,此递归属于间接递归,即:ActionInvocation.invoke()中调用了Interceptor.intercepte(ActionInvocation ai),而Interceptor.intercepte(ai)方法中开发者又调用了ai.invoke(),形成间接递归关系。每次递归index变量值会加一,直到index==inters.length递归终止,此时会调用Controller中的方法。这个设计构成了拦截器对action的环绕型拦截,是一种精巧、简洁、高效的设计。
//作者原话:
if (index < inters.length) {
inters[index++].intercept(this);//逐个处理拦截
}
//拦截器执行完则开始执行controller中的方法
else if (index++ == inters.length) {// index++ ensure invoke action only one time
try {
// Invoke the action
if (action != null) {
returnValue = action.getMethod().invoke(target, args);//调用该controller中的方法
}
// Invoke the method
else {
// if (!Modifier.isAbstract(method.getModifiers()))
// returnValue = methodProxy.invokeSuper(target, args);
if (useInjectTarget)//判断method是否为抽象方法
returnValue = methodProxy.invoke(target, args);
else
returnValue = methodProxy.invokeSuper(target, args);//利用cglib的代理调用父类方法
}
}
catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
throw t instanceof RuntimeException ? (RuntimeException)t : new RuntimeException(e);
}
catch (RuntimeException e) {
throw e;
}
catch (Throwable t) {
throw new RuntimeException(t);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: