寫過了三篇的JFINAL框架源碼的文章,廣泛反響都還不錯,謝謝各位OSC同仁們的關心和支持,從此我會更加勤奮的更新博文和相關的技術文章,好了閒話不說了,由於OSC上面的同仁們來看博文的基本是帶着問題來的,再打廣告會出事的!!進入正題! 記得在第一篇博文的時候就講過一些關於 初始化的事情 主要的操做初始化的操做都在JfinalFiler裏面,再次重申一次就是 Jfinal的入口,今天咱們就深刻的繼續去聊這個初始化的東西。打開JfinalFilter這個文件,看到這句代碼: jfinal.init(jfinalConfig, filterConfig.getServletContext() 就是這一句,咱們的話題就從這裏開始,咱們F3走進去看看,能夠發現,他從上往下的作了一下的初始化工做:java
<!-- lang: java --> 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(); initActiveRecord(); initOreillyCos(); initI18n(); initTokenManager(); return true; }
咱們慢慢的解釋一下各個的初始化過程: 一、initPathUtil();這個是路徑相關的初始化信息程序員
二、Config.configJFinal(jfinalConfig); 這個是加載咱們自定義Config類(也就是咱們在咱們的項目中的繼承JFinalConfig的那個類)中的方法的實現,他的執行順序在JfinalConfig中指定了,其中的原話是這樣的: Config order: configConstant(), configRoute(), configPlugin(), configInterceptor(), configHandler()數據結構
你們能夠看到,他的順序就是這樣,因此,之後若是親愛的程序員們還要去想咱們的JFinalConfig這個加載順序是如何的,這個就是答案!!app
三、constants = Config.getConstants();這個很少說了 配置常量框架
四、initActionMapping();這個是初始化Action映射,底層的數據結構是採用HashMap這種數據集合,經過傳入的字符串去找對應的Action,我認爲這個是JFinal的一個亮點,真的,不少養分都在這裏,有時間咱們好好分析它是如何的有養分jsp
五、initHandler();//這個是處理器的初始化,具體的下次再說 六、initRender();//今天的重點,準備開扒 七、initActiveRecord();//這個是ActiveRecord的初始化,這個是咱們最 八、initOreillyCos();//這個幹嗎的。還在摸索,據推測,應該與文件上傳相關的東西 九、initI18n();//國際化 不用多講了吧 十、initTokenManager();//這個不知道怎麼說....求專業名詞this
initRender()編碼
咱們F3到initRender()中,咱們能夠看到如下的代碼: private void initRender() { RenderFactory renderFactory = RenderFactory.me(); renderFactory.init(constants, servletContext); }spa
能夠看到,在Jfinal中的Render的產生是經過工廠模式來生成的,第一句就是經過RenderFactory的me方法來生成的,其定義以下: private static final RenderFactory me = new RenderFactory(); 這也就是說在咱們的JFinal框架被加載的時候, 咱們就可以獲得一個RenderFactory對象實例,這樣的話 咱們就可以使用這個對象實例進行初始化了。code
下面 咱們來看看renderFactory.init(constants, servletContext)中有啥?
public void init(Constants constants, ServletContext servletContext) { this.constants = constants; RenderFactory.servletContext = servletContext;
// init Render Render.init(constants.getEncoding(), constants.getDevMode()); initFreeMarkerRender(servletContext); initVelocityRender(servletContext); initFileRender(servletContext); // create mainRenderFactory if (mainRenderFactory == null) { ViewType defaultViewType = constants.getViewType(); if (defaultViewType == ViewType.FREE_MARKER) mainRenderFactory = new FreeMarkerRenderFactory(); else if (defaultViewType == ViewType.JSP) mainRenderFactory = new JspRenderFactory(); else if (defaultViewType == ViewType.VELOCITY) mainRenderFactory = new VelocityRenderFactory(); else throw new RuntimeException("View Type can not be null."); } // create errorRenderFactory if (errorRenderFactory == null) { errorRenderFactory = new ErrorRenderFactory(); } }
這裏面主要有下面的事情發生了: 一、Render.init() 在這裏主要是作編碼的設置和開發模式的設置 二、初始化Freemark,Velocity,File 三、經過獲取視圖的值來選擇咱們隨用的視圖種類,如,你是使用Freemark,仍是使用JSP,仍是使用VELOCITY。也能夠看出,JFINAL是支持咱們剛剛提到的三種是視圖的,至於你喜歡哪一個,能夠再Constant裏面設置
當咱們或得了我麼的視圖類型的之後 咱們能夠進入到相應的RenderFactory的中去看看他還爲咱們作了些啥。已JSPRenderFactory爲例: 在RenderFactory中,他定義了一下的代碼:
private static final class JspRenderFactory implements IMainRenderFactory { public Render getRender(String view) { return new JspRender(view); } public String getViewExtension() { return ".jsp"; } } 能夠看到,其中全部的XxxRenderFactory都繼承了一個IMainRenderFactory接口,這裏面的兩個方法都是須要他在被繼承的類中作實現的,這兩個方法是: Render getRender(String view); String getViewExtension(); 這兩個方法的做用是:一個是用來獲取Render的實例,一個是用來獲取視圖的後綴名。 回到咱們的JspRenderFactory 中,咱們能夠看到在實現第一個方法的時候,他放回的時候一個JspRender,實現第二個方法的時候,獲取的後綴名是.jsp,好了,這樣的話就初始化好了咱們Render類型,在調用的時候就可以根據對應的設置來作Render對應的視圖類型了
view參數就是Controller中傳過來的咱們制定的那個跳轉的視圖,那麼這個view在何時下使用了??這裏就簡單說一下 在咱們剛剛的JspRender中有一下代碼: public void render() { try { if (isSupportActiveRecord) supportActiveRecord(request); request.getRequestDispatcher(view).forward(request, response); } catch (Exception e) { throw new RenderException(e); } }
你們有沒有看到熟悉的,大概可以猜到了吧,咱們在咱們出來Action的時候,確定會有一步調用到這個 而後經過 request.getRequestDispatcher(view).forward(request, response); 去跳轉,簡單的就是這麼樣的,具體如何工做的 咱們下次再說!!!
Render()就初始化就是大概就是這樣....