JFinal Handler原始碼解析——從配置到工作原理
JFinal頂層是一個Handler鏈是責任鏈模式的一個變種,會攔截到所有請求,包括靜態資源請求。
首先、我們來看看Handler的配置,我們在JFinal的Config中可用來配置自定義的Handler。
@Override
public void configHandler(Handlers me) {
me.add(new FakeStaticHandler());
}
在這個新增JFinal內建或者我們自己的Handler,在Handlers中有一個ArrayList來儲存她們。
final public class Handlers {
private final List handlerList = new ArrayList();
public Handlers add(Handler handler) {
if (handler != null)
handlerList.add(handler);
return this;
}
public List getHandlerList() {
return handlerList;
}
}
下面、是Handler的初始化,在專案啟動JFinalFilter.init初始化時執行了jfinal.init完成了對整個框架的初始化!我們的Handler也是在這裡完成初始化的。
boolean init(JFinalConfig jfinalConfig, ServletContext servletContext) {
this.servletContext = servletContext;
this.contextPath = servletContext.getContextPath();
initPathUtil();
Config.configJFinal(jfinalConfig); // start plugin and init logger factory in this method
constants = Config.getConstants();
initActionMapping();
initHandler();
initRender();
initOreillyCos();
initTokenManager();
return true;
}
// 初始化Handler
private void initHandler() {
Handler actionHandler = new ActionHandler(actionMapping, constants);
handler = HandlerFactory.getHandler(Config.getHandlers().getHandlerList(), actionHandler);
}
大家再來看看HandlerFactory,在這裡從ArrayList的尾部向頭部迴圈,完成對每個Handler中的nextHandler引數賦值。下面是Handler的結構,她是一個單向的連結串列。
/**
* Handler.
* * You can config Handler in JFinalConfig.configHandler() method,
* Handler can do anything under the jfinal action.
*/
public abstract class Handler {
protected Handler nextHandler;
/**
* Handle target
* @param target url target of this web http request
* @param request HttpServletRequest of this http request
* @param response HttpServletRequest of this http request
* @param isHandled JFinalFilter will invoke doFilter() method if isHandled[0] == false,
* it is usually to tell Filter should handle the static resource.
*/
public abstract void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled);
}
再來、看看HandlerFactory中的getHandler方法。Handler鏈條的末端是ActionHandler,是專門處理action動態請求的地方。
/**
* Build handler chain
*/
public static Handler getHandler(List handlerList, Handler actionHandler) {
Handler result = actionHandler;
for (int i=handlerList.size()-1; i>=0; i--) {
Handler temp = handlerList.get(i);
temp.nextHandler = result;
result = temp;
}
return result;
}
最後、我們來看看Handler是怎麼工作的
上圖描述了JFinal中的一個請求的完整過程JFinalFilter->Handler->Action,請求到達Handler中之後有三種結局。
① 直接跳出鏈條,執行下一個Filter(如果web.xml中有配置)tomcat、jetty容器對靜態資源請求處理。
如果都不滿足,將返回容器級別的404,可在web.xml中配置404頁。*此處的404不受JFinal配置的404頁控制。
靜態資源進入到ActionHandler時會被直接跳出,執行同上。請求不會到達Action。(示例程式碼:JFinal/ActionHandler.java)
if (target.indexOf('.') != -1) {
return ;
}
靜態資源進入到ActionHandler時會被直接跳出,執行同上。請求不會到達Action。(示例程式碼:JFinal/ActionHandler.java)
if (target.indexOf('.') != -1) {
return ;
}
② 請求已經在Handler完成了該有的使命。在Handler執行了render或者在response中返回了我們想要的資料。
該請求也不會到達Action,這裡設定isHandled[0] = true;請求到此為止,也不會去執行後面的Filter。(示例程式碼:jnode/XmlHandler.java)
if (target.endsWith(".xml")) {
String view = target.replace(".xml", ".vm");
RenderFactory.me().getRender("/xml".concat(view)).setContext(request, response).render();
// 跳出
isHandled[0] = true;
return;
}
③ 酒肉穿腸過,佛祖心中留。請求會依次經過各個Handler,抵達Action。
nextHandler.handle(target, request, response, isHandled);
相關推薦
JFinal Handler原始碼解析——從配置到工作原理
JFinal頂層是一個Handler鏈是責任鏈模式的一個變種,會攔截到所有請求,包括靜態資源請求。 首先、我們來看看Handler的配置,我們在JFinal的Config中可用來配置自定義的Handler。 @Override public void c
【Spring實戰】Spring註解配置工作原理原始碼解析
一、背景知識在【Spring實戰】Spring容器初始化完成後執行初始化資料方法一文中說要分析其實現原理,於是就從原始碼中尋找答案,看原始碼容易跑偏,因此應當有個主線,或者帶著問題、目標去看,這樣才能最大限度的提升自身程式碼水平。由於上文中大部分都基於註解進行設定的(Spri
React-從原始碼分析React Fiber工作原理
為什麼要重寫React React16 以前 React16 以前,對virtural dom的更新和渲染是同步的。就是當一次更新或者一次載入開始以後,diff virtual dom並且渲染的過程是一口氣完成的。如果元件層級比較深,相應的堆疊也
從原始碼看hystrix的工作原理
Hystrix是Netflix開源的一個限流熔斷的專案、主要有以下功能: 隔離(執行緒池隔離和訊號量隔離):限制呼叫分散式服務的資源使用,某一個呼叫的服務出現問題不會影響其他服務呼叫。 優雅的降級機制:超時降級、資源不足時(執行緒或訊號量)降級,降級後可以配
深度解析線程工作原理
路徑 cep dead test deadlock end priority interrupt prior 1, 線程的概念 一個程序中的方法有幾條執行路徑, 就有幾個線程 2, 線程的創建 兩種方式: 1, 繼承Thread
Spring原始碼解析 – @Configuration配置類及註解Bean的解析
在分析Spring 容器建立過程時,我們知道容器預設會載入一些後置處理器PostPRocessor,以AnnotationConfigApplicationContext為例,在建構函式中初始化reader時,載入預設後置處理器。其中 ConfigurationClassPostProcessor這個後置
【原創】Mybaitis生命週期原始碼解析-XML配置啟動--轉載請註明出處
一、準備基本程式碼 注:本文的一切內容都是基於XML配置啟動進行的分析,不適用與Spring-mybatis組合使用場景。 1.建立基本類 package com.zhou; import com.zhou.mapper.BlogMapper; import com.zhou.po
# Mybatis原始碼解析之配置載入(二)
Mybatis原始碼解析之配置載入(二) 這一篇是承接上一篇文章Mybatis原始碼解析之配置載入(一),上一篇原本是想把整個配置載入都分析完全,然後發現內容還是比較多,所以決定分成兩篇來說好了,現在就開始剩下的配置分析。 配置載入 繼續回到parseConfigura
Mybatis原始碼解析之配置載入(一)
Mybatis原始碼解析之配置載入(一) 用了好幾年的mybatis了,但是很少來鑽研mybatis原理所在,最近抽出空來,就把這一整套原始碼都研究了下,然後發現就是這些東西,mybatis沒啥難度,於是決定把研究的這一整套寫一個mybatis系列,記錄一下,在這些完了以後,順便寫一
Spring原始碼解析和配置檔案載入
Spring類的繼承結構圖: Spring運用了大量的模板方法模式和策略模式,所以各位看原始碼的時候,務必留意,每一個繼承的層次都有不同的作用,然後將相同的地方抽取出來,依賴抽象將不同的處理按照不同的策略去處理。 步驟A. 讀取 Resource 檔案形成 Documen
Android 8.1 Handler 原始碼解析
原始碼解析,如需轉載,請註明作者:Yuloran (t.cn/EGU6c76) 一. 前言 基於Android 8.1(API27) 原始碼,分析 Handler 的工作流程。 在 Android 系統中,Zygote 程序是首個 java 程序,同時也是所有 java 程序的父程序。上層應用
Handler原始碼解析
Handler物件通過執行緒的MessageQueue,允許你傳送或者處理一個Message物件或者一個Runnable物件。 每一個Handler物件,都與一個單獨的執行緒和執行緒的MessageQueue相關聯。當你建立一個新的Handler物件, 這
Spring原始碼解析——從XmlBeanFactory的建構函式開始看LoadBeanDefinitions
之前的文章聊過ClassPathResource類,通過這個類,我們從classpath載入到了我們的spring配置檔案,之後,就開始執行XmlBeanFactory的構造過程了:public XmlBeanFactory(Resource resource
Android原始碼分析之訊息機制——Handler原始碼解析
Android的訊息機制主要是指Handler的執行機制,Handler是Android訊息機制上層介面的實現,它的執行需要Message、MessageQueue和Looper的支撐,下面就來分別介紹它們的實現原理。 1、Message原始碼解析 首先來了解一下Messag
原始碼解析Fragment 返回棧原理
事務提交 流程 原始碼 事務出棧 流程 原始碼 總結 返回棧涉及的類 在看本文前需要熟悉Fragment 的使用,不清楚的可先看:Fragment使用詳解 本文原始碼都是都是v25 的support v4 包下的原始碼。
Eureka原始碼解析與配置
Eureka只要分為2部分,一個server,一個是client(包含生產者和消費者)。 Eureka client: ①從@EnableEurekaClient註解開始看 ②檢視@EnableDiscoveryClient ③EnableDisco
Binder原始碼解析(從客戶端到服務端程式碼流程)
Binder 解析(從客戶端到服務端程式碼流程) 首先從一個例子開始 服務端程式碼: public class WeatherService extends Service{ IWeatherInterface.Stub stub = new
Handler 原始碼解析
Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { }; }; @Override prot
caffe1原始碼解析從入門到放棄1):記憶體管理syncedmem.hpp / syncedmem.cpp
/*這些程式碼都是本人在linux-nsight-eclipse環境下純手打。 文章結尾都會丟擲一些本人尚未解決的問題,歡迎各路大神拍磚。 文章屬於學習交流性質,隨著本人學力的提升,此blog將會長期修正更新。 * syncedmem.hpp *
理解SAX解析xml的工作原理
當XMLReader讀到<POEM>標籤時,就會呼叫ContentHandler.startDocument()方法,並把標籤名POEM作為引數傳遞過去。在你實現的startElement()方法中需要做相應的動作,以處理當<POEM>出現時應該做的事情。各個事件隨著解析的過程(也就