JFinal初始化分析-常量初始化-1
spring自己基本不熟悉,因為超多的xml配置太繁瑣,就放棄了。自己也不是專做開發的,主要工作是運維。jfianl的出現,無xml配置,令人驚喜。
當時就想學一下這個框架的設計,就找博文來讀,但是發現很多博主一遍贊嘆jfinal的強大,一邊說jfinal的設計很簡單,好像每個博主自己都可以設計一套jfinal一樣,但基本每個博主也都是蜻蜓點水的分析一下啟動或某一塊,然後及基本不再寫了。
我自己覺得jfinal很強大,體量雖然很小,但是設計卻不簡單,相反卻很精巧。可以看出波哥不是因為設計而設計。而是以簡單、快速開發為設計核心的。
要自己設計寫一套jfianl框架,沒有較高的水平,很難。自己覺得jfianl框架不像大家認為的這麽簡單,要設計一套這樣的框架絕非容易的事情。
反之自己抱著學習的態度,希望能搞明白裏面的原理,需要時,也能自己造輪子。
這個算是開始吧,希望能堅持,遇到問題時,也希望能得到波哥的指點。
中間件部署web應用時,會加載web.xml配置文件,並依次listener -> filter -> servlet加載。
1、jfinal的web.xml配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <filter> <filter-name>jfinal</filter-name> <filter-class>com.jfinal.core.JFinalFilter</filter-class> <init-param> <param-name>configClass</param-name> <param-value>app.TestConfig</param-value> </init-param> </filter> <filter-mapping> <filter-name>jfinal</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
可以看出web.xml配置文件沒有配置監聽、和serlvet,只有一個全局過濾器com.jfinal.core.JFinalFilter,可以說,這個過濾器是第一個被加載的class。
過濾器的生命周期是init()->doFilter()->destroy(),init()放一些初始化的信息,doFilter攔截所有請求,並進行處理。
jfinal號稱無xml配置,只要通過一個class就可以完成所有配置,這個class如下:
public class TestConfig extends JFinalConfig{
public void configConstant(Constants constants) {
constants.setDevMode(true);
}
public void configRoute(Routes me) {
me.add("/test",TestController.class);
}
public void configEngine(Engine engine) {
}
public void configPlugin(Plugins plugins) {
}
public void configInterceptor(Interceptors interceptors) {
}
public void configHandler(Handlers handlers) {}
public static void main(String[] args){
JFinal.start("src/main/webapp",8000,"/j");
}
}
可以看出,用時繼承JFinalConfig, 實現以下方法,就可以完成配置,如JFinalConfig源碼:
//配置常量
public abstract void configConstant(Constants var1);
//配置路由
public abstract void configRoute(Routes var1);
//未知
public abstract void configEngine(Engine var1);
//配置插件
public abstract void configPlugin(Plugins var1);
//自定義攔截器,
public abstract void configInterceptor(Interceptors var1);
//過濾鏈,就是全局過濾器的過濾鏈
public abstract void
configHandler(Handlers var1);
從上可以看出,只要繼承JFinalConfig,就可以完成自己的配置,這些配置我們先稱為全局環境配置對象(Constants、Routes、Engine、Interceptors、Handlers等),那這些環境配置是什麽時候被實例化的?
2、JFinal配置的加載 在web.xml配置中,過濾器有個參數,ConfigClass,值是app.TestConfig,就是JFconfigClass的子類,也就是自己的配置class.這說明,我們的配置的class是通過web.xml傳遞給了JFinalFilter過濾器的init()方法。
JFinalFilter的基礎代碼,簡化後的:
public class JFinalFilter implements Filter {
private JFinalConfig jfinalConfig;//TestConfig將會賦值給它。
public void init(FilterConfig filterConfig) {
createJFinalConfig(filterConfig.getInitParameter("configClass"));
}
}
createJFinalConfig的內部實現就是
jfinalConfig =(jfinalConfig)Class.forName("app.TestConfig").newInstance();
這樣就new 了一個app.TestConfig的實例,但是只是實例,並沒有調用裏面的幾個方法,所以方法中的傳遞的環境配置對象還是空的。比如TestConfig:
public void configConstant(Constants constants) {
constants.setDevMode(true);
}
並沒有被執行,所以constants還是空的。這裏涉及兩個問題:
1、誰調用configConstant()方法,並傳遞了Constants 實例對象?
2、Constants 實例化後,如何使用Constants 實例對象?
我們基本可以考慮,這些相關配置對象應該只會被初始化一次,不可能被反復new 出新的對象。那麽可以猜測這些配置的對象應該是單實例,或者static final的來初始化的。
繼續往下看,可以看到是JFinal.init完成了對這些configConstant()方法的調用。
public class JFinalFilter implements Filter {
private JFinalConfig jfinalConfig;//TestConfig將會賦值給它。
public void init(FilterConfig filterConfig) {
//反射生成TestConfig對象實例(<a href="ypj5.com">羊皮卷網</a>)
createJFinalConfig(filterConfig.getInitParameter("configClass"));
//通過調用TestConfig中的方法,完成環境對象的設置,
if (jfinal.init(jfinalConfig, filterConfig.getServletContext()) == false) {
throw new RuntimeException("JFinal init error!");
}
}
}
可以看到,jfinalConfig對象傳遞給了jfinal.init()方法,這個方法返回一個boolean值,如果是false表示初始化失敗了。同時還將ServletContext傳遞給了jfinal.init()方法。下面就需要分析jfinal.init()方法了。可以猜測代碼是這麽樣寫的:
public class JFinal(){
public static final Constants =new Constants();
public static init(JFinalConfig testConfig,ServletContext context){
testConfig.configConstant(Constants);
}
}
這樣就完成了TestConfig.configConstant方法調用,就完成了Constants裏面字段的set()。
JFinal初始化分析-常量初始化-1