你的分享就是我们的动力 ---﹥

JFinal源码分析------初始化那些事儿2之Render

时间:2013-05-21 14:11来源:www.chengxuyuans.com 点击:

记得在第一篇博文的时候就讲过一些关于 初始化的事情 主要的操作初始化的操作都在JfinalFiler里面,再次重申一次就是 Jfinal的入口,今天我们就深入的继续去聊这个初始化的东西。打开JfinalFilter这个文件,看到这句代码: jfinal.init(jfinalConfig, filterConfig.getServletContext() 就是这一句,我们的话题就从这里开始,我们F3走进去看看,可以发现,他从上往下的做了一下的初始化工作:

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;
}

我们慢慢的解释一下各个的初始化过程: 1、initPathUtil();这个是路径相关的初始化信息

2、Config.configJFinal(jfinalConfig); 这个是加载我们自定义Config类(也就是我们在我们的项目中的继承JFinalConfig的那个类)中的方法的实现,他的执行顺序在JfinalConfig中指定了,其中的原话是这样的: Config order: configConstant(), configRoute(), configPlugin(), configInterceptor(), configHandler()

大家可以看到,他的顺序就是这样,所以,以后如果亲爱的程序员们还要去想我们的JFinalConfig这个加载顺序是如何的,这个就是答案!!

3、constants = Config.getConstants();这个不多说了 配置常量

4、initActionMapping();这个是初始化Action映射,底层的数据结构是采用HashMap这种数据集合,通过传入的字符串去找对应的Action,我认为这个是JFinal的一个亮点,真的,很多营养都在这里,有时间我们好好分析它是如何的有营养

5、initHandler();//这个是处理器的初始化,具体的下次再说 6、initRender();//今天的重点,准备开扒 7、initActiveRecord();//这个是ActiveRecord的初始化,这个是我们最 8、initOreillyCos();//这个干嘛的。还在摸索,据推测,应该与文件上传相关的东西 9、initI18n();//国际化 不用多讲了吧 10、initTokenManager();//这个不知道怎么说....求专业名词

initRender()

我们F3到initRender()中,我们可以看到以下的代码: private void initRender() { RenderFactory renderFactory = RenderFactory.me(); renderFactory.init(constants, servletContext); }

可以看到,在Jfinal中的Render的产生是通过工厂模式来生成的,第一句就是通过RenderFactory的me方法来生成的,其定义如下: private static final RenderFactory me = new RenderFactory(); 这也就是说在我们的JFinal框架被加载的时候, 我们就能够得到一个RenderFactory对象实例,这样的话 我们就能够使用这个对象实例进行初始化了。

下面 我们来看看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();
    }
}

这里面主要有下面的事情发生了: 1、Render.init() 在这里主要是做编码的设置和开发模式的设置 2、初始化Freemark,Velocity,File 3、通过获取视图的值来选择我们随用的视图种类,如,你是使用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()就初始化就是大概就是这样....

转载注明地址:http://www.chengxuyuans.com/Javaframework/61308.html