精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (2)
|
|
---|---|
作者 | 正文 |
发表时间:2010-03-19
最后修改:2010-03-19
struts2从2007年初推出第一个稳定的版本到现在已经发展了近3个年头,现在,在新的产品或项目中,如果选用了struts方案,一般都选择了struts2,并非为用struts2而用struts2,我想一定是它的优秀吸引着我们。
在struts2中,value stack和ognl这两个概念非常重要。由于我们大多数人都是从struts1过渡到struts2的,思想的转变是需要一些时间,更重要的是需要一些实践的,因而,我们在使用struts2的时候,常常有些类似于struts1的形式,例如,我们来看一个action的代码: package com.javaeye.hnylj.action; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.interceptor.ServletRequestAware; import com.javaeye.hnylj.model.UserInfo; import com.javaeye.hnylj.service.UserInfoService; import com.opensymphony.xwork2.ActionSupport; /** * UserAction * * @since Mar 15, 2010 */ public class UserAction extends ActionSupport implements ServletRequestAware { private static final long serialVersionUID = 7815936222081975676L; private HttpServletRequest request; private String id; private String name; private UserInfoService userInfoService; public void setServletRequest(HttpServletRequest request) { this.request = request; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public UserInfoService getUserInfoService() { return userInfoService; } public void setUserInfoService(UserInfoService userInfoService) { this.userInfoService = userInfoService; } /** * list users * * @return success * @throws Exception */ @Override public String execute() throws Exception { // 注:userInfoService通过spring注入 List<UserInfo> userList = userInfoService.getUserList(); request.setAttribute("id", id); request.setAttribute("name", name); request.setAttribute("userList", userList); return SUCCESS; } }
从上面的代码中,我们明显感觉到,这与struts1的代码模式非常相似,而常常我们在代码中又是这样写的,当然这样也是完全可以的。 而作为struts2的代码应该是这样的: package com.javaeye.hnylj.action; import java.util.List; import com.javaeye.hnylj.model.UserInfo; import com.javaeye.hnylj.service.UserInfoService; import com.opensymphony.xwork2.ActionSupport; /** * UserAction * * @since Mar 15, 2010 */ public class UserAction extends ActionSupport { private static final long serialVersionUID = 7815936222081975676L; private String id; private String name; List<UserInfo> userList; private UserInfoService userInfoService; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<UserInfo> getUserList() { return userList; } public void setUserList(List<UserInfo> userList) { this.userList = userList; } public UserInfoService getUserInfoService() { return userInfoService; } public void setUserInfoService(UserInfoService userInfoService) { this.userInfoService = userInfoService; } /** * list users * * @return success * @throws Exception */ @Override public String execute() throws Exception { // 注:userInfoService通过spring注入 userList = userInfoService.getUserList(); return SUCCESS; } }
简单比较这两段代码,引起我思考的是这两种代码模式在性能上的不同,我们知道,在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中引起系统性能的一点思考,欢迎大家提出异议,一起交流,共同进步!
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-03-22
最后修改:2010-03-22
1. 你说的第一种情况吃力不讨好, 估计没人会这样做(除非没看过demo)
2. jstl? 怎么不用S2的标签库呢 3. request确实少用, 但还是习惯在父类注入request和session |
|
返回顶楼 | |
发表时间:2010-03-22
S2的标签用着不爽,还是jstl强大
|
|
返回顶楼 | |
发表时间:2010-03-22
最后修改:2010-03-22
楼主要获取HttpServletRequest,很容易,建立一个ServletRequestListener,当requestInitialized方法调用之后,把Request对象放到ThreadLocal里面即可。
|
|
返回顶楼 | |
发表时间:2010-03-22
我发这个帖子主要是说明这样一个观点:在struts2中不应该将数据(包括从客户端传递的参数或从数据库查询的数据)放到request中,这会消耗不必要的内存资源。当然我们在Action中有时也会使用request,session,但我想说的是,不要滥用它,不能是不是都往request中放,这是我们应该注意的。
|
|
返回顶楼 | |
发表时间:2010-03-22
有数据说明?
你可以试试get、set方法情况下debug, request对象里面还是会带值的 hnylj 写道 我发这个帖子主要是说明这样一个观点:在struts2中不应该将数据(包括从客户端传递的参数或从数据库查询的数据)放到request中,这会消耗不必要的内存资源。当然我们在Action中有时也会使用request,session,但我想说的是,不要滥用它,不能是不是都往request中放,这是我们应该注意的。
|
|
返回顶楼 | |
发表时间:2010-03-22
gouflv 写道 2. jstl? 怎么不用S2的标签库呢 jstl会让你的生活而更美好而且简单:because it is standard。jstl发展到1.2,新增了不少tag,让它的功能更强大,比如function、format。以前你无法通过标准库判断一个list的大小,但在1.2中就可以。s2的标签是很强大,有时间和精力就学吧。 |
|
返回顶楼 | |
发表时间:2010-03-23
Struts2的标签用来取值尚可,曾经接受过一个项目,整个工程中没有el没有jstl,甚至界面元素全部都是Struts2标签,痛苦至极
|
|
返回顶楼 | |
发表时间:2010-03-23
不会有人使用第一种方式,发这样的帖子没意义。
|
|
返回顶楼 | |
发表时间:2010-03-23
tibetjungle 写道 gouflv 写道 2. jstl? 怎么不用S2的标签库呢 jstl会让你的生活而更美好而且简单:because it is standard。jstl发展到1.2,新增了不少tag,让它的功能更强大,比如function、format。以前你无法通过标准库判断一个list的大小,但在1.2中就可以。s2的标签是很强大,有时间和精力就学吧。 struts2的tag确实不爽,JSTL,看见大家都说他好, 过两天去看看, |
|
返回顶楼 | |
浏览 4438 次