自学SSH框架之---struts(三):源码分析struts1如何实现Action单例模式

来源:互联网 发布:python基本数据结构 编辑:程序博客网 时间:2024/05/16 08:45

      今天想说的是struts1和struts2的一个区别,就是Struts1 Action是单例模式并且必须是线程安全的,而Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。我们就简单分析源码看看struts1是如何实现Action单例模式的。

       我们借助于自学SSH框架之---struts(二)中的例子来简单分析下。先看看web.xml的配置,如下:

<servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

 

<servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>

这段代码的意思是所有以.do结尾的请求都由ActionServlet来接收。

而请求的方式是什么呢,这个是在jsp页面表明的,先看上一篇博文的login.jsp中有这么一段代码:      <form action="login.do" method="post">,此处的post就表明它要调用ActionServlet的doPost方法。

      好,接下来我们就看看org.apache.struts.action.ActionServlet的doPost方法,

可以看出通过request可以拿到所有的客户端数据,我们再继续看看process方法是什么

这里面的RequestProcessor类的process方法是它的核心处理方法,继续跟进

我们的一次请求就会到达上面的方法里面。

我们就简单说明一下这个方法,对于struts这个请求驱动框架,它会先截取路径,通过 String path = processPath(request, response);把URL截下来,也就是例子中的login ;

接下来通过ActionMapping mapping = processMapping(request, response, path);
        if (mapping == null) {
            return;
        }取得struts-config.xml的配置信息

<action-mappings>里面的
        <action path="/login"
                type="com.bjsxt.struts.LoginAction"
                name="loginForm"
                scope="request"
                validate="false"
        >
            <forward name="success" path="/login_success.jsp"/>
            <forward name="error" path="/login_error.jsp"/>
        </action>
       
    </action-mappings>,那么它是如何得到这些信息的呢?

它是在ActionServlet 第一次初始化的时候,也就是在执行它的init方法的时候,会将上面的xml文件读到内存里面,读到相应的数据结构里面,其中<action></action>内容是怎么读的呢?其实吧,每一个action都会对应一个ActionMapping实例,其中map的key值就是path,map的value就是actionmapping:

<action path="/login"
                type="com.bjsxt.struts.LoginAction"
                name="loginForm"
                scope="request"
                validate="false"
        >
            <forward name="success" path="/login_success.jsp"/>
            <forward name="error" path="/login_error.jsp"/>
        </action>

 

     所以当请求过来后,它会通过ActionMapping mapping = processMapping(request, response, path);去map里面,通过path来找到其对应的配置信息,放到mapping里面,拿到之后通过 ActionForm form = processActionForm(request, response, mapping);处理actionForm,在这里它会判断配置文件配置actionForm没,我们例子它配了  name="loginForm",如果没有它会创建一个actionForm,名字是通过此处<form-bean name="loginForm" type="com.bjsxt.struts.LoginActionForm"/>配置而得的,然后将actionForm放到scope里面。此处要说明的是actionForm是可有可无的,因为有的请求不需要数据的,只是单纯页面的跳转。

 

      好,接下来跳过actionForm收集数据的过程和验证部分,接下来就会调用我们的action了,那么调用action会先创建action,那么怎么创建的呢?它会先拿到 type里面的“com.bjsxt.struts.LoginAction",去map里面看有没有,如果有就直接返回,没有就创建,所以通过这种方式保证我们action是单实例的,好了今天就到此结束了吧,先饭饭了

 

 

原创粉丝点击