- 浏览: 189091 次
- 性别:
- 来自: 武汉
文章分类
最新评论
-
shuaijie506:
以前有点疑惑,现在终于明白了,线程安全是没问题的,想想也是,如 ...
jsp自定义标签 线程安全 -
Laster2800:
原来如此,想不到传统的标记处理器也是线程安全的,受教了。
jsp自定义标签 线程安全 -
GoingForward:
这篇文章是不是可以浓缩为下面几点:1.在非静态内部类中不可以声 ...
static class -
wellse:
呵呵,就是这样!!要的就是这个效果
jsp自定义标签 线程安全 -
xiaohuafyle:
JNDI
我们在编写自定义标签的时候设置属性如下
public class InputTag extends TagSupport { private static final long serialVersionUID = 1L; private String onclick; private String style; private String styleClass; private String value; private String id;
在页面上如果同时使用两个标签:
<h3:input type="button" onclick="myFun()" name="name" id="id" style="style" styleClass="styleClass" value="中国人" url="url" pid="pid" isValidated="true"> 中国人 </h3:input> <h3:input type="button" onclick="myFun()" name="name" id="id" style="style" styleClass="styleClass" value="美国人" url="url" pid="pid" isValidated="true"> </h3:input>
从后台发现打印的InpuTag都是同一个对象!
发现这个后,我十分担心线程安全问题!比如这些getType();setType(); !
于是就看了下jsp生成的Servlet源代码
out.write("\t<body>\r\n"); out.write("\t\t"); //调用InputTag if (_jspx_meth_h3_005finput_005f0(_jspx_page_context)) return; out.write("\r\n"); out.write("\t\t\r\n"); out.write("\t\t"); //调用InputTag if (_jspx_meth_h3_005finput_005f1(_jspx_page_context)) return; out.write("\r\n"); out.write("\t</body>\r\n");
再接着看_jspx_meth_h3_005finput_005f0方法
private boolean _jspx_meth_h3_005finput_005f0(PageContext _jspx_page_context) throws Throwable { PageContext pageContext = _jspx_page_context; JspWriter out = _jspx_page_context.getOut(); // h3:input tag.InputTag _jspx_th_h3_005finput_005f0 = (tag.InputTag) _005fjspx_005ftagPool_005fh3_005finput_0026_005fvalue_005furl_005ftype_005fstyleClass_005fstyle_005fpid_005fonclick_005fname_005fisValidated_005fid.get(tag.InputTag.class); _jspx_th_h3_005finput_005f0.setPageContext(_jspx_page_context); _jspx_th_h3_005finput_005f0.setParent(null); // /button2.jsp(12,2) name = type type = null reqTime = true required = false fragment = false deferredValue = false expectedTypeName = null deferredMethod = false methodSignature = null _jspx_th_h3_005finput_005f0.setType("button"); // /button2.jsp(12,2) name = onclick type = java.lang.String reqTime = false required = true fragment = false deferredValue = false expectedTypeName = null deferredMethod = false methodSignature = null _jspx_th_h3_005finput_005f0.setPid("pid"); // /button2.jsp(12,2) name = isValidated type = null reqTime = true required = false fragment = false deferredValue = false expectedTypeName = null deferredMethod = false methodSignature = null _jspx_th_h3_005finput_005f0.setIsValidated("true"); int _jspx_eval_h3_005finput_005f0 = _jspx_th_h3_005finput_005f0.doStartTag(); if (_jspx_eval_h3_005finput_005f0 != javax.servlet.jsp.tagext.Tag.SKIP_BODY) { do { out.write("\r\n"); out.write("\t\t中国人\r\n"); out.write("\t\t"); int evalDoAfterBody = _jspx_th_h3_005finput_005f0.doAfterBody(); if (evalDoAfterBody != javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN) break; } while (true); } if (_jspx_th_h3_005finput_005f0.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) { _005fjspx_005ftagPool_005fh3_005finput_0026_005fvalue_005furl_005ftype_005fstyleClass_005fstyle_005fpid_005fonclick_005fname_005fisValidated_005fid.reuse(_jspx_th_h3_005finput_005f0); return true; } _005fjspx_005ftagPool_005fh3_005finput_0026_005fvalue_005furl_005ftype_005fstyleClass_005fstyle_005fpid_005fonclick_005fname_005fisValidated_005fid.reuse(_jspx_th_h3_005finput_005f0); return false; }
最关键就是这句了,看他如何获得自定义标签对象: tag.InputTag _jspx_th_h3_005finput_005f0 = (tag.InputTag) _005fjspx_005ftagPool_005fh3_005finput_0026_005fvalue_005furl_005ftype_005fstyleClass_005fstyle_005fpid_005fonclick_005fname_005fisValidated_005fid.get(tag.InputTag.class);
解释下:
_jspx_th_h3_005finput_005f0 是InputTag 的实例 也就是<h3:input.
而
005fjspx_005ftagPool_005fh3_005finput_0026_005fvalue_005furl_005ftype_005fstyleClass_005fstyle_005fpid_005fonclick_005fname_005fisValidated_005
是TagHandlerPool的实例
自定义标签是通过这个TagHandlerPool.get 来获取的!
举一反三,有借就有还TagHandlerPool.reuse用来回收这个对象!
TagHandlerPool.get
TagHandlerPool.reuse
方法如下:
/** * Gets the next available tag handler from this tag handler pool, * instantiating one if this tag handler pool is empty. * * @param handlerClass Tag handler class * * @return Reused or newly instantiated tag handler * * @throws JspException if a tag handler cannot be instantiated */ public Tag get(Class handlerClass) throws JspException { Tag handler = null; synchronized( this ) { if (current >= 0) { handler = handlers[current--]; return handler; } } // Out of sync block - there is no need for other threads to // wait for us to construct a tag for this thread. try { Tag instance = (Tag) handlerClass.newInstance(); AnnotationHelper.postConstruct(annotationProcessor, instance); return instance; } catch (Exception e) { throw new JspException(e.getMessage(), e); } }
/** * Adds the given tag handler to this tag handler pool, unless this tag * handler pool has already reached its capacity, in which case the tag * handler's release() method is called. * * @param handler Tag handler to add to this tag handler pool */ public void reuse(Tag handler) { synchronized( this ) { if (current < (handlers.length - 1)) { handlers[++current] = handler; return; } } // There is no need for other threads to wait for us to release handler.release(); if (annotationProcessor != null) { try { AnnotationHelper.preDestroy(annotationProcessor, handler); } catch (Exception e) { log.warn("Error processing preDestroy on tag instance of " + handler.getClass().getName(), e); } } }
现在就明白了所有的tag对象都是有一个对象池来维护的,一是方便了重用,而是做到了线程同步。
总结:自定义标签是线程安全的,同时也是可重用的!
同时又有另一个疑问
synchronized( this ) {
if (current >= 0) {
handler = handlers[current--];
return handler;
}
}
感觉这种方法可能只能在一个页面上共享,另一个页面上的tag估计是不能共享的!
后来看了下生成的servelt代码
如下:
public void _jspInit() { _tagpool = org.apache.jasper.runtime.TagHandlerPool.getTagHandlerPool(getServletConfig()); _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName()); }
可以看到_tagpool 是根据ServletConifg来生成的
TagHandlerPool.getTagHandlerPool代码如下
public static TagHandlerPool getTagHandlerPool( ServletConfig config) { TagHandlerPool result=null; String tpClassName=getOption( config, OPTION_TAGPOOL, null); if( tpClassName != null ) { try { Class c=Class.forName( tpClassName ); result=(TagHandlerPool)c.newInstance(); } catch (Exception e) { e.printStackTrace(); result=null; } } if( result==null ) result=new TagHandlerPool(); result.init(config); return result; }
评论
发表评论
-
Jetty例子
2010-11-07 22:04 1488import java.io.IOException; ... -
排序面试算法
2010-09-08 08:43 1603从大学到现在,参加过很多面试,经常会被问到一些基本的算法题, ... -
IReport一些注意
2010-09-05 22:02 1315用的是 Ireport2.0版本 更高版本可能没有这个问题 ... -
[转]Java类加载原理解析
2009-11-04 21:47 1159转载 Java 类加载原理解析 ... -
线程上下文类加载器
2009-11-04 21:46 5549线程上下文类加载器 问题:何时使用Thread. ... -
JDBC Sybase
2009-11-04 21:02 4012import java.sql.Connection; im ... -
JDK 5.0 泛型 动态参数 枚举
2009-11-04 21:02 3056import java.util.ArrayList;impo ... -
再看heap 和stack,还有多了解内存
2009-11-03 16:28 1159heap 1.堆石一个“运行时”数据区,类实例化的对象就是从 ... -
java中读取Properties文件
2009-10-23 12:58 1536java 中读取Properties 文 ... -
JNI
2009-10-22 22:15 1419... -
Hibernate经典文章
2009-10-19 12:37 921Lazy Loading (Load&Get) ... -
JNDI
2009-10-15 14:15 2631最近写书,写到JNDI,到处查资料,发现所有的中文资料都对JN ... -
JDBC连接各种数据库
2009-10-14 10:13 935常用JDBC连接数据库方法总结如下: 一、DB2 Cl ... -
java并发的一些题目
2009-09-24 23:41 987a 回答 结果又一下 几种情况 execute here Ca ... -
static class
2009-08-19 14:55 18128在一个类中创建另外 ... -
C++ 对象参数传递
2009-08-07 12:08 1650#include<iostream.h> cla ... -
递归与间接递归
2009-08-07 11:02 48801. 介绍 递归技术允许 ... -
concurrent lib的学习
2009-07-13 17:51 9791.关于BlockingQueue的学习,这是一个阻塞的队列, ... -
应该看的书籍
2009-07-12 21:33 9291.代码大全 2.人月神话 3.设计模式 4.网格计算 ... -
错误总结
2009-07-02 17:46 7601.static inner class和 non-s ...
相关推荐
线程安全就是多线程操作同一个对象不会有问题,线程同步一般来保护线程安全, 所以可以在Servlet的线程里面加上同步方法或同步块。 (Synchronized)可以保证在同一时间只有一个线程访问,(使用同步块会导致性能...
31. Custom Tags I (自定义标签I) 32. Java Standard Tag Library (标准标签库) 33. Expression Language(表达式语言) 34. Expression Language(表达式语言) 35. 使用Java WEB技术编写网页QQ J2EE 框架...
(三) Jsp基本页面标签 116 1. 标签 116 2. contentType属性 118 3. pageEncoding属性 118 (四) form表单中的action,post和get 119 1. form中的action属性 119 2. from中的get和post 120 (五) jsp内置对象(request,...
插件管理功能,支持多插件管理[新增] 每个页面可自定义,设置页面模板[改进] 重写验证码模块代码[新增] 考虑到安全性能,系统禁止了浏览器直接访问jsp页面运行[改进] httpUtils 组件增加1分钟超时,防止无限期等待...
*第十一阶段:JSP开发:JSP语法和标签,自定义标签,EL,JSTL库了解以及MVC三层架构的设计模式理念; *第十二阶段:AJAX开发:AJAX原理,请求响应处理,AJAX开发库; *第十三阶段:轻量级框架,三大框架之一...
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。 HashMap允许将null作为一个entry的key或者...
169 DateFormat 线程安全问题 170 登录页面底部链接问题 172 GAE 版配额消耗过快问题 177 泄漏用户密码安全问题 129 摘要编辑器添加源码功能 132 Markdown 编辑器显示问题 154 使用密文存储密码 155 邮件 SSL...
[新增] 考虑到安全性能,系统禁止了浏览器直接访问jsp页面运行 [改进] httpUtils 组件增加1分钟超时,防止无限期等待 [改进] 定时任务修改为支持多线程,多任务并行运行 s2m企业级整站系统如何安装 下载后,将 ...
11) 编写自定义标签处理类后,需要编写一个()去描述。 a) .tag 文件 b) .tld 文件 c) .dtd文件 d) .xml 文件 12) 关于Tag File说法不正确的是()。 a) Tag File是JSP2.0新增的功能 b) Tag File是JSP...
ThreadImRunnable.java 继承Runnable接口实现多线程 mulThread.java 创建多个线程对象的类 demoJoin.java 演示使用join()以确保主线程最后结束 clicker.java 一个计数用的线程类 demoPri.java 调用上面这个类...
4.4.3 标签语句 4.5 返回语句 4.6 综合实例:水仙花数 4.7 本章习题 第5章 字符串 5.1 字符串简介 5.1.1 字符串常量 5.1.2 String创建字符串常量 5.1.3 StringBuffer创建字符串 5.2 连接字符串 5.2.1 与...
5、支持自定义标签管理,可以灵活定制多种显示效果。 6、文章、栏目模板支持。 7、基于角色的管理机制 8、搜索采用Lucene索引技术,支持任务管理,搜索速度相当于百度、GOOGLE 9、系统自带数据库连接池,性能...
Collections是针对集合类的帮助类,它提供了一系列针对集合的搜索,排序,线程安全化等操作。 final、finally、finalize的区别? 答:final用于声明属性方法和类,分别表示:属性不可变,方法不可覆盖,类不可继承...
Threads:tomcat线程,可以查看线程的状态等信息,还可以杀死线程 Cluster:tomcat集群 System Information:系统信息 Connectors:connector信息,可以看到每秒的请求数、响应时间等 Quick check:...
它非常适合将HTML片段包装为自定义标签并在以后重用。 今天,这个美丽的宝石隐藏在J2EE堆栈的深处。 Facelets精简版实现剥离了所有J2EE / JSF依赖项的Facelets。 它提供了一个简单,干净且简单的库,同时保留并...
自定义标签 613 标准标签的使用 618 内容总结 621 独立实战 622 第三十章:struts入门 623 学习目标 623 Struts简介 624 什么是应用框架 624 WEB框架所要解决的问题 625 建立简单的Struts应用 627 内容总结 636 独立...
4 16 2自定义异常类 4 17Class类 4 17 1获取类的有关信息 4 17 2使用Class实例化一个对象 4 18基本类型的类包装 4 18 1Double类和Float类 4 18 2Byte Integer Short 工 ong类 4 18 3Character类 4 19反编译和文档...
14、JSP中初始化workspace的标签 78 15、JSP中用标签输出一条内容 78 (二)、标签及其功能的使用 78 1、Writing links to Web Content Management content 78 (三)拖放 JSP标记 80 1)<dnd:drag/> 80 2)...
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。 HashMap允许将null作为一个entry的key或者...
14.8.1标签(Jlabel)使用示例488 14.8.2按钮(JButton)使用示例491 14.8.3文本框(JTextField)和密码框(JPasswordField)使用示例492 14.8.4文本区(JTextArea)使用示例496 14.8.5复选框(JcheckBox)使用...