分享

关于struts2中使用request引起系统性能的思考

 AlPacido 2012-10-23

http://hnylj./blog/620097

struts2从2007年初推出第一个稳定的版本到现在已经发展了近3个年头,现在,在新的产品或项目中,如果选用了struts方案,一般都选择了struts2,并非为用struts2而用struts2,我想一定是它的优秀吸引着我们。

 

在struts2中,value stack和ognl这两个概念非常重要。由于我们大多数人都是从struts1过渡到struts2的,思想的转变是需要一些时间,更重要的是需要一些实践的,因而,我们在使用struts2的时候,常常有些类似于struts1的形式,例如,我们来看一个action的代码:

Java代码  收藏代码
  1. package com.javaeye.hnylj.action;  
  2.   
  3. import java.util.List;  
  4. import javax.servlet.http.HttpServletRequest;  
  5. import org.apache.struts2.interceptor.ServletRequestAware;  
  6. import com.javaeye.hnylj.model.UserInfo;  
  7. import com.javaeye.hnylj.service.UserInfoService;  
  8. import com.opensymphony.xwork2.ActionSupport;  
  9.   
  10. /** 
  11.  * UserAction 
  12.  *  
  13.  * @since Mar 15, 2010 
  14.  */  
  15. public class UserAction extends ActionSupport implements ServletRequestAware {  
  16.   
  17.     private static final long serialVersionUID = 7815936222081975676L;  
  18.   
  19.     private HttpServletRequest request;  
  20.   
  21.     private String id;  
  22.   
  23.     private String name;  
  24.   
  25.     private UserInfoService userInfoService;  
  26.   
  27.     public void setServletRequest(HttpServletRequest request) {  
  28.         this.request = request;  
  29.     }  
  30.   
  31.     public String getId() {  
  32.         return id;  
  33.     }  
  34.   
  35.     public void setId(String id) {  
  36.         this.id = id;  
  37.     }  
  38.   
  39.     public String getName() {  
  40.         return name;  
  41.     }  
  42.   
  43.     public void setName(String name) {  
  44.         this.name = name;  
  45.     }  
  46.   
  47.     public UserInfoService getUserInfoService() {  
  48.         return userInfoService;  
  49.     }  
  50.   
  51.     public void setUserInfoService(UserInfoService userInfoService) {  
  52.         this.userInfoService = userInfoService;  
  53.     }  
  54.   
  55.     /** 
  56.      * list users 
  57.      *  
  58.      * @return success 
  59.      * @throws Exception 
  60.      */  
  61.     @Override  
  62.     public String execute() throws Exception {  
  63.         // 注:userInfoService通过spring注入  
  64.         List<UserInfo> userList = userInfoService.getUserList();  
  65.         request.setAttribute("id", id);  
  66.         request.setAttribute("name", name);  
  67.         request.setAttribute("userList", userList);  
  68.         return SUCCESS;  
  69.     }  
  70. }  

 

从上面的代码中,我们明显感觉到,这与struts1的代码模式非常相似,而常常我们在代码中又是这样写的,当然这样也是完全可以的。

而作为struts2的代码应该是这样的:

Java代码  收藏代码
  1. package com.javaeye.hnylj.action;  
  2.   
  3. import java.util.List;  
  4. import com.javaeye.hnylj.model.UserInfo;  
  5. import com.javaeye.hnylj.service.UserInfoService;  
  6. import com.opensymphony.xwork2.ActionSupport;  
  7.   
  8. /** 
  9.  * UserAction 
  10.  *  
  11.  * @since Mar 15, 2010 
  12.  */  
  13. public class UserAction extends ActionSupport {  
  14.   
  15.     private static final long serialVersionUID = 7815936222081975676L;  
  16.   
  17.     private String id;  
  18.   
  19.     private String name;  
  20.   
  21.     List<UserInfo> userList;  
  22.   
  23.     private UserInfoService userInfoService;  
  24.   
  25.     public String getId() {  
  26.         return id;  
  27.     }  
  28.   
  29.     public void setId(String id) {  
  30.         this.id = id;  
  31.     }  
  32.   
  33.     public String getName() {  
  34.         return name;  
  35.     }  
  36.   
  37.     public void setName(String name) {  
  38.         this.name = name;  
  39.     }  
  40.   
  41.     public List<UserInfo> getUserList() {  
  42.         return userList;  
  43.     }  
  44.   
  45.     public void setUserList(List<UserInfo> userList) {  
  46.         this.userList = userList;  
  47.     }  
  48.   
  49.     public UserInfoService getUserInfoService() {  
  50.         return userInfoService;  
  51.     }  
  52.   
  53.     public void setUserInfoService(UserInfoService userInfoService) {  
  54.         this.userInfoService = userInfoService;  
  55.     }  
  56.   
  57.     /** 
  58.      * list users 
  59.      *  
  60.      * @return success 
  61.      * @throws Exception 
  62.      */  
  63.     @Override  
  64.     public String execute() throws Exception {  
  65.         // 注:userInfoService通过spring注入  
  66.         userList = userInfoService.getUserList();  
  67.         return SUCCESS;  
  68.     }  
  69. }  

 

简单比较这两段代码,引起我思考的是这两种代码模式在性能上的不同,我们知道,在struts2中,所有的属性值,包括从客户端传递的参数或从数据库查询的数据,只要在action中对应有此属性变量的定义,并拥有相应的setter与getter方法,这些数据都会被放置到值栈中,在页面我们就可以使用struts2的标签或ognl取得这些值。struts2将这些数据放置到值栈中,肯定是需要耗费一定的内存的,但struts2的过滤器有一种功能就是在使用之后执行ActionContextCleanUp.cleanUp(req),将值栈清空。而我们第一种代码方式,是将所有的数据,包括从客户端传递的参数或从数据库查询的数据都放置到request中,然后在页面通过jstl或el表达式取出request中的值,虽然request在一次请求之后也会把数据销毁,但我想说的是,既然struts2已经将这些数据放置到了值栈中,而我们又将这些数据在request中放置一遍,那么这样一来,每一个action被执行,在数据没有销毁之前,数据在内存中就放置了两份,这无疑会牺牲不必要的内存资源,特别是一些对性能要求较高而硬件配置又有限的情况下。

 

在struts2中,每一个Action是线程安全的,即每一个客户端的请求都会new一个新的Action为其提供服务,如此就会使得,当系统在线人数较多时,会new出较多的Action来为这些在线的用户服务,而当我们使用第一种模式的代码时,每一个Action中都将数据放置到request中,然后通过jstl在页面中显示,这样,request不知要放置多少数据,再加上本来struts2在值栈中也放置了这些数据,那么内存的使用将是成倍数的上升,我们完全可以放弃使用request,因为在struts2中所有的数据会自动放置到值栈中,我做了一点测试,使用第一种模式的代码,我通过查看windows资源管理器的tomcat进程的内存使用,发现它明显高于第二种代码模式的内存使用,另外让我感觉更为兴奋的是,jstl也完全可以取得值栈中的数据,所以你完全可以使用struts2+jstl进行开发。

 

这是我对关于struts2中使用request中引起系统性能的一点思考,欢迎大家提出异议,一起交流,共同进步!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多