论坛首页 Java企业应用论坛

spring3mvc与struts2比较

浏览 162476 次
该帖已经被评为良好帖
作者 正文
   发表时间:2010-06-16  
webwork和struts2的action很容易全局变量泛滥,目前正在深受其害
1 请登录后投票
   发表时间:2010-06-16  
daquan198163 写道
webwork和struts2的action很容易全局变量泛滥,目前正在深受其害


没有发现什么全局变量,请具体说明
0 请登录后投票
   发表时间:2010-06-16   最后修改:2010-06-16
downpour 写道
daquan198163 写道
webwork和struts2的action很容易全局变量泛滥,目前正在深受其害


没有发现什么全局变量,请具体说明

sorry,实例变量
最近解除了一些webwork的遗留代码,发现action里经常是一大堆实例变量,被不同的方法读写,
当然你可以说这是开发人员的问题,但毕竟webwork更容易让人犯这样的错误,
springmvc的controller不是线程安全的,反而避免了这个问题。
0 请登录后投票
   发表时间:2010-06-16   最后修改:2010-06-16
daquan198163 写道
downpour 写道
daquan198163 写道
webwork和struts2的action很容易全局变量泛滥,目前正在深受其害


没有发现什么全局变量,请具体说明

sorry,实例变量
最近解除了一些webwork的遗留代码,发现action里经常是一大堆实例变量,被不同的方法读写,
当然你可以说这是开发人员的问题,但毕竟webwork更容易让人犯这样的错误,
springmvc的controller不是线程安全的,反而避免了这个问题。

1.最早的servlet就是线程不安全的,一般不能使用实例变量。
2.你碰到的案例完全就是遗留代码自身的编程问题,和框架没什么关系吧。说穿了就是action这一级逻辑代码的分布问题,是放在一个class中、or根据逻辑再拆分到不同的class(action)而已。
3.struts2的框架允许自定义某个action是单例(非线程安全)还是多例的,用注解或配置文件很容易设置的。
0 请登录后投票
   发表时间:2010-06-16  
daquan198163 写道
downpour 写道
daquan198163 写道
webwork和struts2的action很容易全局变量泛滥,目前正在深受其害


没有发现什么全局变量,请具体说明

sorry,实例变量
最近解除了一些webwork的遗留代码,发现action里经常是一大堆实例变量,被不同的方法读写,
当然你可以说这是开发人员的问题,但毕竟webwork更容易让人犯这样的错误,
springmvc的controller不是线程安全的,反而避免了这个问题。


Action的实例变量有什么问题?被不同的方法读写又有什么问题?我没有看到存在的问题。反而,有属性,也有方法的Java类才是面向对象的。一个连属性都没有的Java类,怎么说也OO不到哪里去。

另外就是你们在开发Action的时候,对Action的定义界定一定不是十分清楚。Struts2所期望的Action定义并不是将多数的操作都封装到一个Action里面。比如,你把所有的增删改查的业务操作全部放到一个Action里面,一定会造成Action中的实例变量多得无法维护。
1 请登录后投票
   发表时间:2010-06-22  
zdmcjm 写道
to wen66
不用做压力测试也知道啦,光看@Name这种运行时注解就知道,他的性能不会好到哪,再看到他的动态注入方式,还双向,更加不要对他的性能抱希望啦。所以我说悲哀啊,seam是在正确的使用java,但是。。。



注解和性能没有关系,Servlet的生命周期是这样的,在调用这个Servlet时候才创建这个Servlet的类并运行init()方法,然后另外有人运行这个Servlet的时候并没有重启创建Servlet和运行里边的init()方法,所以Servlet容器时单利的,spring就是Servlet的封装的框架,包括所有的依赖注入都是在tomcat启动的时候全部被初始化的,其他的注解也一样,也就是说注解也就是以前的xml的配置的替代,以前没个请求都要运行一次xml吗?并不是的,xml是在tomcat启动时就读一次而已并利用里边的配置初始化很多的东西,然后就不在使用了,因为都成了单利的,这样就保证了效率,不是每次都把我们要注入的全部new一次,而是tomcat启动的时候全部new一次以后就不new了,保证了效率问题。


所以我不明白那个 光看注解就知道性能不好?
注解就是替代了xml配置而已,而且也是初始化一次,也就是说和编写Servlet一样的在init()中做了很多的事而已,并且以后不会在运行init()了,除非你重启tomcat。

struts1也一样,运行一个action的方法的时候创建一个action类,以后再运行就不会创建了,其实也是Servlet的封装的框架。

struts2特殊一些,没个请求要new一个action来保证线程安全。所以效率会低一些,但是不会低的特别离谱。

这样也说明了spring3的mvc和struts1的mvc还有Servlet都是方法的线程安全,所以在类方法声明的私有或者公有变量不是线程安全的,struts2的确实是线程安全的。

所有各有各的好处,用什么当然是仁者见仁智者见智了。

不过我们确实在新项目中大量的使用了spring3,因为REST挺好的。
0 请登录后投票
   发表时间:2010-06-23  
downpour 写道
daquan198163 写道
downpour 写道
daquan198163 写道
webwork和struts2的action很容易全局变量泛滥,目前正在深受其害


没有发现什么全局变量,请具体说明

sorry,实例变量
最近解除了一些webwork的遗留代码,发现action里经常是一大堆实例变量,被不同的方法读写,
当然你可以说这是开发人员的问题,但毕竟webwork更容易让人犯这样的错误,
springmvc的controller不是线程安全的,反而避免了这个问题。


Action的实例变量有什么问题?被不同的方法读写又有什么问题?我没有看到存在的问题。反而,有属性,也有方法的Java类才是面向对象的。一个连属性都没有的Java类,怎么说也OO不到哪里去。

另外就是你们在开发Action的时候,对Action的定义界定一定不是十分清楚。Struts2所期望的Action定义并不是将多数的操作都封装到一个Action里面。比如,你把所有的增删改查的业务操作全部放到一个Action里面,一定会造成Action中的实例变量多得无法维护。

Struts2的action虽然是线程安全的,但是设计时确实需要注意,一个action里面需要组合那些方法和实例变量。
一种做法是把对象相关的CRUD甚至其他方法和用到的变量全部放在Action里面。
class CustomerAction{
    private String cusId;
    private String toCusId;
    private Customer cus;
    private List<Customer> cusList;
    
    //use cusList as result.
    public String search(){
       ...
    }
    
    //use cus as result, cusId as input.
    public String load(){
        cus = service.load(cusId);
    }
    
    //use cus as input.
    public void create(){
        ...
    }
    
    //use cusId, toCusId as input
    public void copy(){
        ...
    }
    
    //other method.
    ...
}

好处:
1.实现快速。
缺陷:
1.同一个cusId在多个方法里面被用到,而且可能在不同方法里面有不同含义,也不知道是用于输入还是输出。
2.每次调用会生成无用的instance variable, 比如cusList.
随着这个类功能不断增加,实例变量的混乱使用不可避免,每次对象的生成也将更慢。

我个人认为以上做法甚至是反OO的,因为没有做到很好的职责分离。
我的建议是按页面划分action,或者按功能划分action.

按功能划分action
class CustomerCreateAction{
    private Customer cus;
    //use cus as input.
    public void create(){
        ...
    }
}

优点:
结构清晰。Action重用性强。
缺点:
类太多。

按页面划分action
class CustomerEditPageAction{
    //对应页面编辑的cus对象。
    private Customer cus;
    
    //对应客户列表。
    private List cusList;

    //对应创建按钮事件.
    public void create(){
        ...
    }
}

优点:
结构清晰,实例变量和方法易于理解。
缺点:
和页面耦合严重,action重用性差。

我个人喜欢最后一种。
0 请登录后投票
   发表时间:2010-06-23   最后修改:2010-06-23
框架是死的,人是活的。

如果对Struts默认的获取参数的方式不是很感冒,完全可以利用现成的很多工具方法,自己获取参数,尤其是一些非表单的参数,这样就不需要那么多set方法,可以一定程度的减少楼上说的第二种情况中的冲突。

还有页面和功能的划分也可以灵活一点的,因为还有些项目中还有很多Ajax请求呢。
0 请登录后投票
   发表时间:2010-06-23  
有关Struts2的Action职责问题。我认为可以根据功能模块进行划分。一个功能模块,一般会有2到3个Action,每个Action将承担一定的职责。

比如User相关的功能模块。可能需要2个比较基本的Action:UserController和UserView。UserController负责User相关的操作,UserView负责User显示的相关操作。如果User这个功能模块太大,比如牵涉到User的权限,那么就需要增加新的Action,例如UserRoleController和UserRoleView。

无论怎么说,按照Controller和View进行Action的功能分类,是目前为止我认为比较合理的一种方式。View的操作对象往往是id和entity本身,所以这2个变量会在一个Action中共享,你根本不用去担心某个parameter是for哪个操作的。你的关注点只要停留在你的操作本身就可以了。
0 请登录后投票
   发表时间:2010-06-23  
downpour 写道
有关Struts2的Action职责问题。我认为可以根据功能模块进行划分。一个功能模块,一般会有2到3个Action,每个Action将承担一定的职责。

比如User相关的功能模块。可能需要2个比较基本的Action:UserController和UserView。UserController负责User相关的操作,UserView负责User显示的相关操作。如果User这个功能模块太大,比如牵涉到User的权限,那么就需要增加新的Action,例如UserRoleController和UserRoleView。

无论怎么说,按照Controller和View进行Action的功能分类,是目前为止我认为比较合理的一种方式。View的操作对象往往是id和entity本身,所以这2个变量会在一个Action中共享,你根本不用去担心某个parameter是for哪个操作的。你的关注点只要停留在你的操作本身就可以了。

感觉这样划分并不易把握。我觉得一个页面一个action是最好操作的,虽然可能会形成一些冗余,但是可维护性很好。
0 请登录后投票
论坛首页 Java企业应用版

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