锁定老帖子 主题:struts不好吗,为什么总有人骂她.
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间: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 $ */ |
|
返回顶楼 | |
发表时间:2004-07-27
dhj1 写道 STRUTS是很强大的,但是强大的东西有个弱点,就是对初学者来说太难学习了. 所以很多人骂STRUTS.这是非常正常的.
很多人骂STRUTS的人,并没有多少STRUTS的实战经验.如果你精通STRUTS,能运用自如,你会骂他吗? 只有你用不习惯或者用的很烂.才会骂它. 也可以从这个角度上来说明STRUTS的强大,越是强大的东西越是不容易学习. 强大的功能自然是肯定的。 但是这个不足于弥补它技术上的失败。 struts已经发展了很久了,功能确实在逐年增加,这些都源于庞大开发人群在使用它!为什么那么多人在使用它呢?有历史的原因也有它所提供的强大的功能的原因。可是当你发现它所具备的缺点之后,这一切都已经失去意义!而它所提供的功能别的MVC框架都已经初步跟上,struts它的这点唯一的优势也在逐步失去。 |
|
返回顶楼 | |
发表时间: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的特性没有太大的必要,启动之后做一遍,将结果全部缓存就好了嘛)。 |
|
返回顶楼 | |
发表时间: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的。 哥们智力不错! |
|
返回顶楼 | |
发表时间: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解决。 我后面说的两点呢?有没有问题?如有,请及时指出,免得误导大家。多谢。 |
|
返回顶楼 | |
发表时间: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?
|
|
返回顶楼 | |
发表时间:2004-07-31
2000个用户同时在线?那只能尽可能做到服务器端无状态,只有这样才能发挥缓存的全部效用,并且将缓存的负面影响降低到最小
我一直在考虑哪里是维护状态的最好选择,想来想去还是客户端,用cookie。可cookie方案对用户带有一定的强迫性。 |
|
返回顶楼 | |
发表时间:2004-08-14
我没有选择stucts的理由
1、设计思想为了mvc而mvc,造成设计出来了的产品的单一,在很多项目中需要为了模式而套用模式,这个是我极为反对的,我喜欢是多复杂的系统就做多复杂的设计,而不是为了满足复杂的设计而设计系统 2、配置复杂,维护困难的,非常多的mapping的地方,xml的维护到最后困难程度我觉得比代码维护好不了多少的,纯粹是为了延长jsp的生存期的 3、tag以及行为表现端设计难以和美工沟通,需要你的程序员是多面手的 我觉得其实阻碍我走向struts的最大阻碍是在很多时候他会带给我很多不必要的设计和麻烦,所以到现在为止 我使用的大部分是他的思想而不是struts本身的。 ps:我喜欢digester,beanutils,validator因为他们才是真正的轮子 |
|
返回顶楼 | |
发表时间:2004-08-14
那为啥像HP,ORACLE,SAP在做项目时,只要是web应用都会选择Struts呢? oracle的ADF框架和Struts非常紧密地绑在了一起,通过Jdeveloper的图形化的设计方式极大程度的加快了程序的开发速度。 所以,我感觉Struts其实已经是一个广泛采用的技术, 它的优点很明显,但是它也有过于复杂的地方。对于公司的上层领导来说,比如说我们的总监,他就知道struts非常好的web层的框架,而且我们公司对struts有很好的GUI支持,如果你不用,你就得回答为什么你不用,我觉得给他们解释技术上的优劣是没有意义的,你没有任何有力的证据证明你采用的其他设计比struts更好而他可以说我们公司的产品很多都使用了struts而且都很成功。 对于设计而言,不同的环境,不同的工具,不同的使用工具的人就会有其相对应的设计方案。
willmac兄所言有道理,但有的时候现实情况是你要让你的老大相信你的系统设计正确,最简单的方法就是用他知道的成熟的设计方案。 |
|
返回顶楼 | |
发表时间:2004-08-14
我没有说反对struts的意思,我只是说我在实际使用中
没有使用它的框架,是因为在不少业务上,如果使用struts会增加不少不必要的麻烦的,这可能是因为所作 产品的定位,和这些公司不一样,更多时候,我们需要的 是好用实际的产品,而不是求全通用的东西 |
|
返回顶楼 | |