jinfeng_wang

G-G-S,D-D-U!

BlogJava 首页 新随笔 联系 聚合 管理
  400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks

http://hi.baidu.com/yanhua365/blog/item/a05930ad04b777094a36d662.html

页面中太多的自定义标签会不会影响性能?

太多的自定义标签(尤其是这种包含了一部分业务逻辑的标签)会不会影响性能呢?下面一段文字是我以前写的,可以说明一些问题,但真正对性能会不会产生太大的影响,还要看具体的情况,如果有必要的话,做一下性能测试得出的结果才是可靠的。

我们知道,JSP归根到底是Servlet,也就是说最终是要编译成Servlet的。如果是在Servlet的service方法中new一个Tag处理类来处理出现的标签的话,那就意味着每一次客户的请求都会生成新的Tag处理类,这样对服务器的性能和资源影响都很大。而如果把Tag处理类的对象做为Servlet的一个属性的话,又会遇到线程安全等问题。据说,不同的JSP容器有不同的处理方式,有的容器下,一个页面上出现太多的自定义标签,响应速度就会很慢。真担心太多的JSP和太多的自定义标签会使服务器承受不了啊。--今天突然想到,可以看一下Tomcat是怎么把包含有自定义标签的JSP页面编译成Servlet的,也许就清楚自定义标签对性能的影响有多大了!
原来,Tomcat用了缓冲池的概念来解决。。。
比如我在JSP中用到了一个Struts标签<html:text property="username"></html:text>那么,在对应的JSP编译的Servlet中会有一个这样的属性private org.apache.jasper.runtime.TagHandlerPool _jspx_tagPool_html_text_property;可以看出来,这是Tomcat提供的一个标签处理的缓冲池,在下面会用到它。在Servlet中会生成下面这个方法:
 private boolean _jspx_meth_html_text_0(javax.servlet.jsp.tagext.JspTag _jspx_th_html_form_0, PageContext pageContext)
          throws Throwable {
    JspWriter out = pageContext.getOut();
    /* ----  html:text ---- */
    org.apache.struts.taglib.html.TextTag _jspx_th_html_text_0 = (org.apache.struts.taglib.html.TextTag) _jspx_tagPool_html_text_property.get(org.apache.struts.taglib.html.TextTag.class);
    _jspx_th_html_text_0.setPageContext(pageContext);
    if (_jspx_th_html_form_0 instanceof javax.servlet.jsp.tagext.SimpleTag)
      _jspx_th_html_text_0.setParent(new javax.servlet.jsp.tagext.TagAdapter((javax.servlet.jsp.tagext.SimpleTag) _jspx_th_html_form_0));
    else
      _jspx_th_html_text_0.setParent((javax.servlet.jsp.tagext.Tag) _jspx_th_html_form_0);
    _jspx_th_html_text_0.setProperty("username");
    int _jspx_eval_html_text_0 = _jspx_th_html_text_0.doStartTag();
    if (_jspx_th_html_text_0.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE)
      return true;
    _jspx_tagPool_html_text_property.reuse(_jspx_th_html_text_0);
    return false;
  }
可以看出,在这个方法中,对标签处理类做了缓冲池处理,可以大大提高性能。
当然,_jspx_tagPool_html_text_property这个Servlet的属性,要在初始化时赋值,在最后释放掉。
public void _jspInit() {
        _jspx_tagPool_html_text_property = org.apache.jasper.runtime.TagHandlerPool.getTagHandlerPool(getServletConfig());

 public void _jspDestroy() {
        _jspx_tagPool_html_text_property.release();

需要说明的是,这种缓冲池是在这个JSP生命周期的范围内的,也就是说,另一个JSP页面用到了相同的标签,也会重新建立一个缓冲池,和这个页面毫无关系。还有一点,就是在同一个JSP页面中,也不是一个标签对应一个缓冲池,比如说我用到了link标签的两种形式,它们属性的个数是不一样的:
   <html:link action="/test">Test with a link</html:link>
    <html:link action="/test" paramId="username" paramName="haha">
那就会生成两个缓冲池:
    private org.apache.jasper.runtime.TagHandlerPool _jspx_tagPool_html_link_action;
   private org.apache.jasper.runtime.TagHandlerPool _jspx_tagPool_html_link_paramName_paramId_action;
这样,虽然服务器上会有很多这样的缓冲池,不过相对于每次请求创建Tag处理类来说,这不算什么,大大提高了性能和利用了服务器资源。
我们这里说的都是Tomcat的解决方案,至于其它容器,也许有不同的解决方案。

posted on 2008-03-05 16:10 jinfeng_wang 阅读(1303) 评论(0)  编辑  收藏 所属分类: javaZZ

只有注册用户登录后才能发表评论。


网站导航: