欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

jsp自定義標簽 線程安全

系統 1983 0

?

轉自: http://klcwt.iteye.com/blog/749652

?

我們在編寫自定義標簽的時候設置屬性如下

Java代碼 ? ? 收藏代碼
  1. public ? class ?InputTag? extends ?TagSupport?{??
  2. ??
  3. ???? private ? static ? final ? long ?serialVersionUID?=?1L;??
  4. ??
  5. ???? private ?String?onclick;??
  6. ??
  7. ???? private ?String?style;??
  8. ??
  9. ???? private ?String?styleClass;??
  10. ??
  11. ???? private ?String?value;??
  12. ??
  13. ???? private ?String?id;??

?

在頁面上如果同時使用兩個標簽:

Html代碼 ? ? 收藏代碼
  1. < h3:input ? type = "button" ? onclick = "myFun()" ? name = "name" ? id = "id" ??
  2. ???????? style = "style" ? styleClass = "styleClass" ? value = "中國人" ? url = "url" ??
  3. ???????? pid = "pid" ? isValidated = "true" > ??
  4. ????中國人??
  5. ???? </ h3:input > ??
  6. ??????
  7. ???? < h3:input ? type = "button" ? onclick = "myFun()" ? name = "name" ? id = "id" ??
  8. ???????? style = "style" ? styleClass = "styleClass" ? value = "美國人" ? url = "url" ??
  9. ???????? pid = "pid" ? isValidated = "true" > ??
  10. ???? </ h3:input > ??

?

從后臺發現打印的InpuTag都是 同一個對象!

?

發現這個后,我十分擔心線程安全問題!比如這些getType();setType(); !

?

于是就看了下jsp生成的Servlet源代碼

Java代碼 ? ? 收藏代碼
  1. out.write( "\t<body>\r\n" );??
  2. ??out.write( "\t\t" );??
  3. ??? //調用InputTag ??
  4. ?? if ?(_jspx_meth_h3_005finput_005f0(_jspx_page_context))??
  5. ???? return ;??
  6. ??out.write( "\r\n" );??
  7. ??out.write( "\t\t\r\n" );??
  8. ??out.write( "\t\t" );??
  9. ?? //調用InputTag ??
  10. ?? if ?(_jspx_meth_h3_005finput_005f1(_jspx_page_context))??
  11. ???? return ;??
  12. ??out.write( "\r\n" );??
  13. ??out.write( "\t</body>\r\n" );??

?

再接著看_jspx_meth_h3_005finput_005f0方法

Java代碼 ? ? 收藏代碼
  1. ?? private ? boolean ?_jspx_meth_h3_005finput_005f0(PageContext?_jspx_page_context)??
  2. ?????????? throws ?Throwable?{??
  3. ????PageContext?pageContext?=?_jspx_page_context;??
  4. ????JspWriter?out?=?_jspx_page_context.getOut();??
  5. ???? //??h3:input ??
  6. ???<span?style= "color:?#ff0000;" >?tag.InputTag?<span?style= "color:?#0000ff;" >_jspx_th_h3_005finput_005f0</span>?=?(tag.InputTag)?_005fjspx_005ftagPool_005fh3_005finput_0026_005fvalue_005furl_005ftype_005fstyleClass_005fstyle_005fpid_005fonclick_005fname_005fisValidated_005fid.get(tag.InputTag. class );</span>??
  7. ????_jspx_th_h3_005finput_005f0.setPageContext(_jspx_page_context);??
  8. ????_jspx_th_h3_005finput_005f0.setParent( null );??
  9. ???? //?/button2.jsp(12,2)?name?=?type?type?=?null?reqTime?=?true?required?=?false?fragment?=?false?deferredValue?=?false?expectedTypeName?=?null?deferredMethod?=?false?methodSignature?=?null ??
  10. ????_jspx_th_h3_005finput_005f0.setType( "button" );??
  11. ???? //?/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"); ??
  12. ???? //?/button2.jsp(12,2)?name?=?isValidated?type?=?null?reqTime?=?true?required?=?false?fragment?=?false?deferredValue?=?false?expectedTypeName?=?null?deferredMethod?=?false?methodSignature?=?null ??
  13. ????_jspx_th_h3_005finput_005f0.setIsValidated( "true" );??
  14. ???? int ?_jspx_eval_h3_005finput_005f0?=?_jspx_th_h3_005finput_005f0.doStartTag();??
  15. ???? if ?(_jspx_eval_h3_005finput_005f0?!=?javax.servlet.jsp.tagext.Tag.SKIP_BODY)?{??
  16. ?????? do ?{??
  17. ????????out.write( "\r\n" );??
  18. ????????out.write( "\t\t中國人\r\n" );??
  19. ????????out.write( "\t\t" );??
  20. ???????? int ?evalDoAfterBody?=?_jspx_th_h3_005finput_005f0.doAfterBody();??
  21. ???????? if ?(evalDoAfterBody?!=?javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN)??
  22. ?????????? break ;??
  23. ??????}? while ?( true );??
  24. ????}??
  25. ???? if ?(_jspx_th_h3_005finput_005f0.doEndTag()?==?javax.servlet.jsp.tagext.Tag.SKIP_PAGE)?{??
  26. ??????<span?style= "color:?#ff0000;" >_005fjspx_005ftagPool_005fh3_005finput_0026_005fvalue_005furl_005ftype_005fstyleClass_005fstyle_005fpid_005fonclick_005fname_005fisValidated_005fid.reuse(_jspx_th_h3_005finput_005f0);</span>??
  27. ?????? return ? true ;??
  28. ????}??
  29. <span?style= "color:?#ff0000;" >????_005fjspx_005ftagPool_005fh3_005finput_0026_005fvalue_005furl_005ftype_005fstyleClass_005fstyle_005fpid_005fonclick_005fname_005fisValidated_005fid.reuse(_jspx_th_h3_005finput_005f0);</span>??
  30. ???? return ? false ;??
  31. ??}??

最關鍵就是這句了,看他如何獲得自定義標簽對象: 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

方法如下:

?

Java代碼 ? ? 收藏代碼
  1. /** ?
  2. ??*?Gets?the?next?available?tag?handler?from?this?tag?handler?pool, ?
  3. ??*?instantiating?one?if?this?tag?handler?pool?is?empty. ?
  4. ??* ?
  5. ??*?@param?handlerClass?Tag?handler?class ?
  6. ??* ?
  7. ??*?@return?Reused?or?newly?instantiated?tag?handler ?
  8. ??* ?
  9. ??*?@throws?JspException?if?a?tag?handler?cannot?be?instantiated ?
  10. ??*/ ??
  11. ? public ?Tag?get(Class?handlerClass)? throws ?JspException?{??
  12. g?handler?=? null ;??
  13. ????? synchronized (? this ?)?{??
  14. ????????? if ?(current?>=? 0 )?{??
  15. ?????????????handler?=?handlers[current--];??
  16. ????????????? return ?handler;??
  17. ?????????}??
  18. ?????}??
  19. ??
  20. ????? //?Out?of?sync?block?-?there?is?no?need?for?other?threads?to ??
  21. ????? //?wait?for?us?to?construct?a?tag?for?this?thread. ??
  22. ????? try ?{??
  23. ?????????Tag?instance?=?(Tag)?handlerClass.newInstance();??
  24. ?????????AnnotationHelper.postConstruct(annotationProcessor,?instance);??
  25. ????????? return ?instance;??
  26. ?????}? catch ?(Exception?e)?{??
  27. ????????? throw ? new ?JspException(e.getMessage(),?e);??
  28. ?????}??
  29. ?}??

?

Java代碼 ? ? 收藏代碼
  1. /** ?
  2. ?*?Adds?the?given?tag?handler?to?this?tag?handler?pool,?unless?this?tag ?
  3. ?*?handler?pool?has?already?reached?its?capacity,?in?which?case?the?tag ?
  4. ?*?handler's?release()?method?is?called. ?
  5. ?* ?
  6. ?*?@param?handler?Tag?handler?to?add?to?this?tag?handler?pool ?
  7. ?*/ ??
  8. public ? void ?reuse(Tag?handler)?{??
  9. ???? synchronized (? this ?)?{??
  10. ???????? if ?(current?<?(handlers.length?-? 1 ))?{??
  11. ????????????handlers[++current]?=?handler;??
  12. ???????????? return ;??
  13. ????????}??
  14. ????}??
  15. ???? //?There?is?no?need?for?other?threads?to?wait?for?us?to?release ??
  16. ????handler.release();??
  17. ???? if ?(annotationProcessor?!=? null )?{??
  18. ???????? try ?{??
  19. ????????????AnnotationHelper.preDestroy(annotationProcessor,?handler);??
  20. ????????}? catch ?(Exception?e)?{??
  21. ????????????log.warn( "Error?processing?preDestroy?on?tag?instance?of?" ???
  22. ????????????????????+?handler.getClass().getName(),?e);??
  23. ????????}??
  24. ????}??
  25. }??

?

?

現在就明白了所有的tag對象都是有一個對象池來維護的,一是方便了重用,而是做到了線程同步。

?

?總結:自定義標簽是線程安全的,同時也是可重用的!


?

同時又有另一個疑問

?synchronized( this ) {
??????????? if (current >= 0) {
??????????????? handler = handlers[current--];
??????????????? return handler;
??????????? }
??????? }

感覺這種方法可能只能在一個頁面上共享,另一個頁面上的tag估計是不能共享的!

?

后來看了下生成的servelt代碼

如下:

Java代碼 ? ? 收藏代碼
  1. public ? void ?_jspInit()?{??
  2. ????_tagpool?=?org.apache.jasper.runtime.TagHandlerPool.getTagHandlerPool(getServletConfig());??
  3. ????_el_expressionfactory?=?_jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();??
  4. ????_jsp_annotationprocessor?=?(org.apache.AnnotationProcessor)?getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor. class .getName());??
  5. ??}??

?可以看到_tagpool 是根據ServletConifg來生成的

TagHandlerPool.getTagHandlerPool代碼如下

Java代碼 ? ? 收藏代碼
  1. public ? static ?TagHandlerPool?getTagHandlerPool(?ServletConfig?config)?{??
  2. ???????TagHandlerPool?result= null ;??
  3. ??
  4. ???????String?tpClassName=getOption(?config,?OPTION_TAGPOOL,? null );??
  5. ??????? if (?tpClassName?!=? null ?)?{??
  6. ??????????? try ?{??
  7. ???????????????Class?c=Class.forName(?tpClassName?);??
  8. ???????????????result=(TagHandlerPool)c.newInstance();??
  9. ???????????}? catch ?(Exception?e)?{??
  10. ???????????????e.printStackTrace();??
  11. ???????????????result= null ;??
  12. ???????????}??
  13. ???????}??
  14. ??????? if (?result== null ?)?result= new ?TagHandlerPool();??
  15. ???????result.init(config);??
  16. ??
  17. ??????? return ?result;??
  18. ???}??

?

jsp自定義標簽 線程安全


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 天天草天天干天天 | 91麻豆精东果冻天美传媒老狼 | 夜夜操狠狠操 | 欧美日韩不卡 | 成人性大片免费观看网站 | 一本色道久久综合狠狠躁 | 成片免费观看视频在线网 | 99re在线| 91亚洲国产成人久久精品网站 | 国产成人精品.一二区 | 末成年毛片在线播放 | 欧美乱码精品一区 | 久久久久亚洲精品 | 久久久精彩视频 | 国产免费黄色网址 | 日本一区二区高清不卡 | 精品一区视频 | 精品国产乱码久久久久久丨区2区 | 精品免费av | 欧洲色吧 | 国产精品久久久久久久久久久久冷 | 日韩少妇成熟A片无码专区 黄在线免费观看 | 久久精品亚洲精品 | 欧美性高清bbbbbbxxxxx | 96福利视频 | 久久久久国产一区二区三区 | 中文字幕亚洲欧美日韩在线不卡 | www.91在线 | 午夜精品久久久久久久99黑人 | 国产精品国产三级在线专区 | 国产一级毛片夜一级毛片 | 毛片网站在线 | 激情一区 | 日韩欧美日本 | 国产真人做爰视频免费 | 国产精品美女网站在线看 | 欧美99| 久久五月婷 | 日韩在线免费视频 | 国产午夜精品一区二区三区嫩草 | 久久99国产精品免费网站 |