日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

jsp自定義標(biāo)簽 線程安全

系統(tǒng) 2136 0

?

轉(zhuǎn)自: http://klcwt.iteye.com/blog/749652

?

我們?cè)诰帉?xiě)自定義標(biāo)簽的時(shí)候設(shè)置屬性如下

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;??

?

在頁(yè)面上如果同時(shí)使用兩個(gè)標(biāo)簽:

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

?

從后臺(tái)發(fā)現(xiàn)打印的InpuTag都是 同一個(gè)對(duì)象!

?

發(fā)現(xiàn)這個(gè)后,我十分擔(dān)心線程安全問(wèn)題!比如這些getType();setType(); !

?

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

Java代碼 ? ? 收藏代碼
  1. out.write( "\t<body>\r\n" );??
  2. ??out.write( "\t\t" );??
  3. ??? //調(diào)用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. ?? //調(diào)用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中國(guó)人\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. ??}??

最關(guān)鍵就是這句了,看他如何獲得自定義標(biāo)簽對(duì)象: 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 的實(shí)例 也就是<h3:input.

005fjspx_005ftagPool_005fh3_005finput_0026_005fvalue_005furl_005ftype_005fstyleClass_005fstyle_005fpid_005fonclick_005fname_005fisValidated_005

是TagHandlerPool的實(shí)例

?

自定義標(biāo)簽是通過(guò)這個(gè)TagHandlerPool.get 來(lái)獲取的!

舉一反三,有借就有還TagHandlerPool.reuse用來(lái)回收這個(gè)對(duì)象!

?

?

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. }??

?

?

現(xiàn)在就明白了所有的tag對(duì)象都是有一個(gè)對(duì)象池來(lái)維護(hù)的,一是方便了重用,而是做到了線程同步。

?

?總結(jié):自定義標(biāo)簽是線程安全的,同時(shí)也是可重用的!


?

同時(shí)又有另一個(gè)疑問(wèn)

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

感覺(jué)這種方法可能只能在一個(gè)頁(yè)面上共享,另一個(gè)頁(yè)面上的tag估計(jì)是不能共享的!

?

后來(lái)看了下生成的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 是根據(jù)ServletConifg來(lái)生成的

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自定義標(biāo)簽 線程安全


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

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

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 嵩明县| 惠州市| 哈尔滨市| 清流县| 白朗县| 工布江达县| 山西省| 营山县| 呈贡县| 鹿邑县| 建平县| 华宁县| 乡城县| 聂拉木县| 临高县| 米林县| 饶河县| 新龙县| 嫩江县| 双牌县| 乌拉特后旗| 天长市| 玉林市| 封丘县| 兴城市| 军事| 广州市| 万州区| 若尔盖县| 中西区| 诏安县| 饶阳县| 云霄县| 新兴县| 镇原县| 河北区| 芒康县| 墨竹工卡县| 克拉玛依市| 富裕县| 梁河县|