论坛首页 Java企业应用论坛

struts不好吗,为什么总有人骂她.

浏览 38960 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-07-27  
引用
1. 关于Struts Action的误解
Struts Action是为每一个Request对应一个Action实例的。并没有共享同一个Action实例。只是使用了pooling技术,可以回收用完的Action实例,以备为下一个Request使用。

这是在Action类中看到的:
/**
 * An <strong>Action</strong> is an adapter between the contents of an incoming
 * HTTP request and the corresponding business logic that should be executed to
 * process this request.  The controller (ActionServlet); will select an
 * appropriate Action for each request, create an instance (if necessary);,
 * and call the <code>perform</code> method.</p>
 *
 * <p>Actions must be programmed in a thread-safe manner, because the
 * controller will share the same instance for multiple simultaneous
 * requests.  This means you should design with the following items in mind:
 * </p>
 * <ul>
 * <li>Instance and static variables MUST NOT be used to store information
 *     related to the state of a particular request.  They MAY be used to
 *     share global resources across requests for the same action.</li>
 * <li>Access to other resources (JavaBeans, session variables, etc.); MUST
 *     be synchronized if those resources require protection.  (Generally,
 *     however, resource classes should be designed to provide their own
 *     protection where necessary.</li>
 * </ul>
 *
 * <p>When an <code>Action</code> instance is first created, the controller
 * servlet will call <code>setServlet();</code> with a non-null argument to
 * identify the controller servlet instance to which this Action is attached.
 * When the controller servlet is to be shut down (or restarted);, the
 * <code>setServlet();</code> method will be called with a <code>null</code>
 * argument, which can be used to clean up any allocated resources in use
 * by this Action.</p>
 *
 * @author Craig R. McClanahan
 * @author David Graham
 * @version $Revision: 1.61 $ $Date: 2003/06/28 06:16:34 $
 */
0 请登录后投票
   发表时间:2004-07-27  
dhj1 写道
STRUTS是很强大的,但是强大的东西有个弱点,就是对初学者来说太难学习了. 所以很多人骂STRUTS.这是非常正常的.

很多人骂STRUTS的人,并没有多少STRUTS的实战经验.如果你精通STRUTS,能运用自如,你会骂他吗? 只有你用不习惯或者用的很烂.才会骂它.

也可以从这个角度上来说明STRUTS的强大,越是强大的东西越是不容易学习.

强大的功能自然是肯定的。
但是这个不足于弥补它技术上的失败。
struts已经发展了很久了,功能确实在逐年增加,这些都源于庞大开发人群在使用它!为什么那么多人在使用它呢?有历史的原因也有它所提供的强大的功能的原因。可是当你发现它所具备的缺点之后,这一切都已经失去意义!而它所提供的功能别的MVC框架都已经初步跟上,struts它的这点唯一的优势也在逐步失去。
0 请登录后投票
   发表时间:2004-07-28  
我们一直在误解Struts?

buaawhl 写道

1. 关于Struts Action的误解
Struts Action是为每一个Request对应一个Action实例的。并没有共享同一个Action实例。只是使用了pooling技术,可以回收用完的Action实例,以备为下一个Request使用。

莫非我们对于Struts的认识——限制代码必须线程安全,都是错的?那为什么 Struts 中用 Hibernate 要借助 ThreadLocal 呢?莫非那些高手们都是为了炫耀?

buaawhl 写道

Struts源代码
org.apache.struts.action包,RequestProcessor类。
    protected Action processActionCreate(HttpServletRequest request,
                                         HttpServletResponse response,
                                         ActionMapping mapping);
        throws IOException {
        
        Action instance = null;
        synchronized (actions); {
            // Return any existing Action instance of this class
            instance = (Action); actions.get(className);;
            if (instance != null); {
                return (instance);;
            }
            // Create and return a new Action instance
            try {
                instance = (Action); RequestUtils.applicationInstance(className);;
                // TODO Maybe we should propagate this exception instead of returning
                // null.
            } catch (Exception e); {
                response.sendError(
                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                    getInternal();.getMessage("actionCreate", mapping.getPath();););;
                return (null);;
            }
            instance.setServlet(this.servlet);;
            actions.put(className, instance);;
        }
        return (instance);;
    }



格式太乱,简化一下,嘿嘿,先不管它的功能,单看逻辑好了。

    protected Action processActionCreate(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping); throws IOException {
        Action instance = null;
        synchronized (actions); {
            instance = (Action); actions.get(className);;
            if (instance == null); {
                instance = (Action); RequestUtils.applicationInstance(className);;
                instance.setServlet(this.servlet);;
                // 留意这一句,下一次的执行 actions.get(className); 就不会返回null了。
                // 如果是Pooling,这里应该有“出列”以及在另外一个方法中(用完之后的事件);“归队”的操作。
                actions.put(className, instance);;
            }
        }
        return (instance);;
    }


哦,这里做的原来不是Pooling,而是Instance过程的结果缓存(个人觉得,这个RuntimeInstance的特性没有太大的必要,启动之后做一遍,将结果全部缓存就好了嘛)。
0 请登录后投票
   发表时间:2004-07-29  
zzeric 写道
冰云 写道
现在有深切体会!!

struts,嘿,好死不死的偏要学servlet的初始化方法。
一个Action只有一个实例。

这下可好,由于所有的线程共享一个Action,所有的与请求有关的参数,都要通过execute(xxxxx)传递到方法中。

以前还好,凑合用。可现在用IOC了,还怎么继续用这样的烂接口?

为了保证不会在多线程情况下处问题,你不能保存request,response实例,需要用的话就得一个个传递到别的函数中,造成了函数签名污染

而webwork不是这样。它是对每一个Thread创建一个Action(应该是)

tapestry和jsf等,和action更是不同,根本就没有了显式的request,COP~~虽说问题也是多多。

不过,总的比较起来,我还是倾向于webwork而不是struts。 至于tapestry,嘿嘿,希望等下一版本呢


如果你不喜欢Struts的传统处理模式,希望每个请求用一个独立的action对象来处理的话,可以这样:
public abstract class BaseAction extends Action
{
       public ActionForward execute(......);
       {
             BaseAction action = (BaseAction);this.getClass();.newInstance();;
             return action.doExecute(......);;
       }
       
       protected abstract ActionForward doExecute();;
}

public class ActionA extends BaseAction
{
     .....

     public ActionForward doExecute(....);
     {
              ............
              return mapping.findForward(.....);;
     }
}


这样线程间就不会相互干扰。

同理,如果想像WW2那样通过ActionContext得到request,而不用老是要通过传参的方法得到request,也只要在BaseAction里把Action放到ThreadLocal里,然后写一个类似ActionContext的辅助类就可以实现了。

当然这只是为了弥补Struts的缺陷而已,我自己也是偏向使用WW2的。


哥们智力不错!
0 请登录后投票
   发表时间:2004-07-29  
jackyz 写道
我们一直在误解Struts?

格式太乱,简化一下,嘿嘿,先不管它的功能,单看逻辑好了。

    protected Action processActionCreate(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping); throws IOException {
        Action instance = null;
        synchronized (actions); {
            instance = (Action); actions.get(className);;
            if (instance == null); {
                instance = (Action); RequestUtils.applicationInstance(className);;
                instance.setServlet(this.servlet);;
                // 留意这一句,下一次的执行 actions.get(className); 就不会返回null了。
                // 如果是Pooling,这里应该有“出列”以及在另外一个方法中(用完之后的事件);“归队”的操作。
                actions.put(className, instance);;
            }
        }
        return (instance);;
    }


哦,这里做的原来不是Pooling,而是Instance过程的结果缓存(个人觉得,这个RuntimeInstance的特性没有太大的必要,启动之后做一遍,将结果全部缓存就好了嘛)。


看到你的分析。我知道是我犯了错误,是我误解了。感谢指正。
那段代码做的不是pooling, 只是一个结果缓存。我看代码太草率,感觉那段代码象是从队列中取出来,因为struts对ActionForm就是这么做的。有些想当然了。

感谢指正。

对于这一个共享的instance来说,如果有共享的可写可读的成员变量,那么确实有 线程安全问题。需要用ThreadLocal解决。

我后面说的两点呢?有没有问题?如有,请及时指出,免得误导大家。多谢。
0 请登录后投票
   发表时间:2004-07-29  
Hi, everyone.  Our project has its own MVC model.  The function is like Struts.  It works well.  Now I am thinking about how to deal with cocurrency control and cache issue.  I was wondering if there is cache machanism and concurrency control in Struts.  Does anybody use Struts to deal with 2000 clients online together?
0 请登录后投票
   发表时间:2004-07-31  
2000个用户同时在线?那只能尽可能做到服务器端无状态,只有这样才能发挥缓存的全部效用,并且将缓存的负面影响降低到最小

我一直在考虑哪里是维护状态的最好选择,想来想去还是客户端,用cookie。可cookie方案对用户带有一定的强迫性。
0 请登录后投票
   发表时间:2004-08-14  
我没有选择stucts的理由
1、设计思想为了mvc而mvc,造成设计出来了的产品的单一,在很多项目中需要为了模式而套用模式,这个是我极为反对的,我喜欢是多复杂的系统就做多复杂的设计,而不是为了满足复杂的设计而设计系统
2、配置复杂,维护困难的,非常多的mapping的地方,xml的维护到最后困难程度我觉得比代码维护好不了多少的,纯粹是为了延长jsp的生存期的
3、tag以及行为表现端设计难以和美工沟通,需要你的程序员是多面手的
我觉得其实阻碍我走向struts的最大阻碍是在很多时候他会带给我很多不必要的设计和麻烦,所以到现在为止
我使用的大部分是他的思想而不是struts本身的。
ps:我喜欢digester,beanutils,validator因为他们才是真正的轮子
0 请登录后投票
   发表时间:2004-08-14  
那为啥像HP,ORACLE,SAP在做项目时,只要是web应用都会选择Struts呢?  oracle的ADF框架和Struts非常紧密地绑在了一起,通过Jdeveloper的图形化的设计方式极大程度的加快了程序的开发速度。 所以,我感觉Struts其实已经是一个广泛采用的技术, 它的优点很明显,但是它也有过于复杂的地方。对于公司的上层领导来说,比如说我们的总监,他就知道struts非常好的web层的框架,而且我们公司对struts有很好的GUI支持,如果你不用,你就得回答为什么你不用,我觉得给他们解释技术上的优劣是没有意义的,你没有任何有力的证据证明你采用的其他设计比struts更好而他可以说我们公司的产品很多都使用了struts而且都很成功。 对于设计而言,不同的环境,不同的工具,不同的使用工具的人就会有其相对应的设计方案。
willmac兄所言有道理,但有的时候现实情况是你要让你的老大相信你的系统设计正确,最简单的方法就是用他知道的成熟的设计方案。
0 请登录后投票
   发表时间:2004-08-14  
我没有说反对struts的意思,我只是说我在实际使用中
没有使用它的框架,是因为在不少业务上,如果使用struts会增加不少不必要的麻烦的,这可能是因为所作
产品的定位,和这些公司不一样,更多时候,我们需要的
是好用实际的产品,而不是求全通用的东西
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics