• struts1源码阅读(1)


        用struts1也有不短的日子了,对于它的功能也有了一定的理解。基于此,抱着学习的态度,我计划在空闲时间来系统的看下struts1的源码。之所以说系统,是因为之前断断续续的也看过一些,但限于当时对struts1的了解,体会得可能还不深入,所以总是容易忘记看过的东西。但现在来读 struts1的源码,应该会更加合适一些,有几个方面的因素,而这几个因素,我觉得也可以用在阅读其他项目的源码上:

        1、首先,我对struts1的功能有了一定的了解,虽然还不够精通,但对其整体的框架和体系是有一定认知的;

        2、其次,能够区分struts1的各功能模块,这样在阅读源码时就会有的放矢,各个击破了。

    struts1工作流程

        先让我们来看看struts1的工作流程,从宏观上对struts1的功能有个认知。

        从网上找了两张图:

        struts1的体系结构图:

    struts1体系结构

        struts1的工作流程图:

    struts1流程图

        1、初始化:struts框架的总控制器ActionServlet是一个Servlet,它在web.xml中配置成自动启动的

    Servlet,在启动时总控制器会读取配置文件(struts-config.xml)的配置信息,为struts

    中不同的模块初始化相应的对象。

        2、发送请求:用户提交表单或通过URLWEB服务器提交请求,请求的数据用HTTP协议传给web服务器。

        3、form填充:struts的总控制器ActionServlet在用户提交请求时将数据放到对应的form对象中的成员

    变量中。

        4、派发请求:控制器根据配置信息对象ActionConfig将请求派发到具体的Action,对应的formBean一并

    传给这个Action中的excute()方法。

        5、处理业务:Action一般只包含一个excute()方法,它负责执行相应的业务逻辑(调用其它的业务模块)

    完毕后返回一个ActionForward对象。服务器通过ActionForward对象进行转发工作。

        6、返回响应:Action将业务处理的不同结果返回一个目标响应对象给总控制器。

        7、查找响应:总控制器根据Action处理业务返回的目标响应对象,找到对应的资源对象,一般情况下

    jsp页面。

        8、响应用户:目标响应对象将结果传递给资源对象,将结果展现给用户。

    struts1初始化

        下面开始我们的源码阅读之旅,首先,对struts1的初始化源码进行阅读。

        web容器在初始化或者初始化完成后,会在适当的时候初始化servlet。struts1中的ActionServlet类就是一个servlet,其会被web容器进行调用。

        首先会调用init()方法,该方法会执行如下动作:

        1、initInternal()

        初始化struts内部使用的消息资源。

        2、initOther()

        2.1 读取初始化参数config,如果在web.xml中对该参数进行了设置,则将ActionServlet类中的config字段设置上对应的值。该值记录的是默认情况下,struts配置文件的路径。

        2.2 读取初始化参数convertNull,如果设置为true(可为true、yes、on、y、1),则将原始类型的封装类默认值设置为null。

        3、initServlet()

        利用Digester组件解析web.xml,将当前servlet对应的<servlet-mapping>内容加载到ActionServlet中。关键代码如下:

    1. protected void initServlet() throws ServletException {  
    2.   
    3.         // Remember our servlet name  
    4.         this.servletName = getServletConfig().getServletName();  
    5.   
    6.         // Prepare a Digester to scan the web application deployment descriptor  
    7.         Digester digester = new Digester();  
    8.         digester.push(this);  
    9.         digester.setNamespaceAware(true);  
    10.         digester.setValidating(false);  
    11.   
    12.         // Register our local copy of the DTDs that we can find  
    13.         for (int i = 0; i < registrations.length; i += 2) {  
    14.             URL url = this.getClass().getResource(registrations[i+1]);  
    15.             if (url != null) {  
    16.                 digester.register(registrations[i], url.toString());  
    17.             }  
    18.         }  
    19.   
    20.         // Configure the processing rules that we need  
    21.         digester.addCallMethod("web-app/servlet-mapping",  
    22.                                "addServletMapping"2);  
    23.         digester.addCallParam("web-app/servlet-mapping/servlet-name"0);  
    24.         digester.addCallParam("web-app/servlet-mapping/url-pattern"1);         
    25.   
    26.         InputStream input =  
    27.             getServletContext().getResourceAsStream("/WEB-INF/web.xml");  
    28.   
    29.         try {  
    30.             digester.parse(input);  
    31.   
    32.         } catch (IOException e) {  
    33.             log.error(internal.getMessage("configWebXml"), e);  
    34.             throw new ServletException(e);  
    35.   
    36.         } catch (SAXException e) {  
    37.             log.error(internal.getMessage("configWebXml"), e);  
    38.             throw new ServletException(e);  
    39.   
    40.         } finally {  
    41.             try {  
    42.                 input.close();  
    43.             } catch (IOException e) {  
    44.                 log.error(internal.getMessage("configWebXml"), e);  
    45.                 throw new ServletException(e);  
    46.             }  
    47.         }  
    48.     }  

        在解析时,会调用ActionServlet类中的addServletMapping()方法,该方法会根据当前servlet对应servletName去匹配对应的url-pattern。

        4、initModuleConfigFactory()

        初始化创建模块配置对象的工厂类,将初始化参数configFactory指定的类名赋予ModuleConfigFactory类的factoryClass字段。

        5、对web.xml中配置的多个模块分别进行解析,生成不同的moduleConfig对象。主要代码如下:

    1. // Initialize modules as needed  
    2.            ModuleConfig moduleConfig = initModuleConfig("", config);  
    3.            initModuleMessageResources(moduleConfig);  
    4.            initModuleDataSources(moduleConfig);  
    5.            initModulePlugIns(moduleConfig);  
    6.            moduleConfig.freeze();  
    7.      
    8.            Enumeration names = getServletConfig().getInitParameterNames();  
    9.            while (names.hasMoreElements()) {  
    10.                String name = (String) names.nextElement();  
    11.                if (!name.startsWith("config/")) {  
    12.                    continue;  
    13.                }  
    14.                String prefix = name.substring(6);  
    15.                moduleConfig = initModuleConfig  
    16.                    (prefix, getServletConfig().getInitParameter(name));  
    17.                initModuleMessageResources(moduleConfig);  
    18.                initModuleDataSources(moduleConfig);  
    19.                initModulePlugIns(moduleConfig);  
    20.                moduleConfig.freeze();  
    21.            }  

        在方法initModuleConfig()中,会根据生成一个工厂对象,该工厂会根据各模块前缀生成不同的ModuleConfig对象。

        这里,很明显的使用到了抽象工厂模式。为了对抽象工厂模式有更深的理解,在这里也多说几句。

    抽象工厂模式类图


        ModuleConfigFactory是一个抽象类,它有一个抽象方法createModuleConfig()供子类实现,该方法就是用来生产 ModuleConfig对象的。在Struts1中,有个默认的工厂实现类DefaultModuleConfigFactory,该类负责生产 ModuleConfigImpl对象。

        ModuleConfigFactory的实现子类可以在web.xml中进行配置,通过调用setFactoryClass()和createFactory()方法,可以生成具体的工厂类。

        抽象工厂模式定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
        在生成了ModuleConfig对象后,会利用Digester组件对struts的配置文件进行解析,解析后的内容会放入ModuleConfig对象。

     转载地址:  http://blog.csdn.net/duwenchao1986/article/details/8464794

  • 相关阅读:
    使用Fiddler和雷电模拟器抓取安卓https请求
    Robot Framework -- 安装接口测试库
    Robot Framework --为了进行Web测试,安装SeleniumLibrary外部库
    robotframework+python3+eclipse+RED自动化测试框架初学笔记
    LeetCode Weekly Contest 27
    LeetCode Weekly Contest 26
    京东4.7实习笔试题
    牛客网模拟笔试 2
    4.1几道最近的题目
    网易3.25实习笔试
  • 原文地址:https://www.cnblogs.com/lishoubin/p/3211286.html
Copyright © 2020-2023  润新知