乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      groovy 模板引擎實(shí)現(xiàn)原理分析

       CevenCheng 2012-11-25

      groovy 模板引擎實(shí)現(xiàn)原理分析








      groovy的SimpleTemplateEngine實(shí)現(xiàn)了模板功能,類似于jsp。那就分析groovy是如何實(shí)現(xiàn)模板的。 

      使用模板 

      Java代碼
      1. 1.Template template = new SimpleTemplateEngine().createTemplate(   
      2. 2.        new StringReader("<% // This is a comment that will be filtered from output %>\n" +   
      3. 3.        "Hello <%out.println(name);%> !")   
      4. 4.    );   
      5. 5.  
      6. 6.    final StringWriter sw = new StringWriter();   
      7. 7.    template.make([name:'bloodwolf_china').writeTo(sw);   
      8. 8.    println sw.toString();  
      9. Template template = new SimpleTemplateEngine().createTemplate(
      10.         new StringReader("<% // This is a comment that will be filtered from output %>\n" +
      11.         "Hello <%out.println(name);%> !")
      12.     );

      13.     final StringWriter sw = new StringWriter();
      14.     template.make([name:'bloodwolf_china').writeTo(sw);
      15.     println sw.toString();
      復(fù)制代碼
      看看SimpleTemplateEngine類 

      Java代碼
      1. 1.public Template createTemplate(Reader reader) throws CompilationFailedException, IOException {   
      2. 2.        SimpleTemplate template = new SimpleTemplate();   
      3. 3.        String script = template.parse(reader);   
      4. 4.                 
      5. 5.            template.script = groovyShell.parse(script, "SimpleTemplateScript" + counter++ + ".groovy");   
      6. 6.          
      7. 7.        return template;   
      8. 8.    }  
      9. public Template createTemplate(Reader reader) throws CompilationFailedException, IOException {
      10.         SimpleTemplate template = new SimpleTemplate();
      11.         String script = template.parse(reader);
      12.               
      13.             template.script = groovyShell.parse(script, "SimpleTemplateScript" + counter++ + ".groovy");
      14.        
      15.         return template;
      16.     }
      復(fù)制代碼
      這兒做了三件事 
      1、創(chuàng)建了一個(gè)SimpleTemplate對(duì)象 
      2、解析模板,主要是把<%=exp%>轉(zhuǎn)為groovy的內(nèi)置表達(dá)式${exp},把非<%code%>轉(zhuǎn)為調(diào)用out.print(內(nèi)容)函數(shù),<%code%>中的就是groovy代碼了。這樣就把整個(gè)模板解析為一段代碼。如
      引用
      Hello <%out.println(name);%> !
      變成 

      Java代碼
      1. 1.out.print("Hello ");   
      2. 2.out.println(name);   
      3. 3.out.print(" !");  
      4. out.print("Hello ");
      5. out.println(name);
      6. out.print(" !");
      復(fù)制代碼
      3、用groovyShell獲取一個(gè)Script對(duì)象 

      Script對(duì)象只一個(gè)支持普通groovy對(duì)象,利用了Groovy的特性 
      實(shí)現(xiàn) getProperty(String property)方法,從參數(shù)綁定對(duì)象中獲取屬性,這樣腳本中就能獲取綁定參數(shù)。 

      Java代碼
      1. 1.public abstract class Script extends GroovyObjectSupport {   
      2. 2.    private Binding binding;   
      3. 3.    public Object getProperty(String property) {   
      4. 4.        try {   
      5. 5.            return binding.getVariable(property);   
      6. 6.        } catch (MissingPropertyException e) {   
      7. 7.            return super.getProperty(property);   
      8. 8.        }   
      9. 9.    }   
      10. 10.     public abstract Object run();   
      11. 11.}  
      12. public abstract class Script extends GroovyObjectSupport {
      13.     private Binding binding;
      14.     public Object getProperty(String property) {
      15.         try {
      16.             return binding.getVariable(property);
      17.         } catch (MissingPropertyException e) {
      18.             return super.getProperty(property);
      19.         }
      20.     }
      21.      public abstract Object run();
      22. }
      復(fù)制代碼
      groovyShell把一段代碼組裝成一個(gè)GroovyCodeSource對(duì)象,然后調(diào)用GroovyClassLoader,CompilationUnit把CodeSource編譯成一個(gè)Script對(duì)象,run()方法中執(zhí)行的即是out.print(模板內(nèi)容)這段代碼。 

      在看看如何輸出模板內(nèi)容的 

      Java代碼
      1. 1.private static class SimpleTemplate implements Template {   
      2. 2.  
      3. 3.        protected Script script;   
      4. 4.  
      5. 5.        public Writable make() {   
      6. 6.            return make(null);   
      7. 7.        }   
      8. 8.  
      9. 9.        public Writable make(final Map map) {   
      10. 10.            return new Writable() {   
      11. 11.                /**  
      12. 12.                 * Write the template document with the set binding applied to the writer.  
      13. 13.                 *  
      14. 14.                 * @see groovy.lang.Writable#writeTo(java.io.Writer)  
      15. 15.                 */  
      16. 16.                public Writer writeTo(Writer writer) {   
      17. 17.                    Binding binding;   
      18. 18.                    if (map == null)   
      19. 19.                        binding = new Binding();   
      20. 20.                    else  
      21. 21.                        binding = new Binding(map);   
      22. 22.                    Script scriptObject = InvokerHelper.createScript(script.getClass(), binding);   
      23. 23.                    PrintWriter pw = new PrintWriter(writer);   
      24. 24.                    scriptObject.setProperty("out", pw);   
      25. 25.                    scriptObject.run();   
      26. 26.                    pw.flush();   
      27. 27.                    return writer;   
      28. 28.                }   
      29. 29.  
      30. 30.                /**  
      31. 31.                 * Convert the template and binding into a result String.  
      32. 32.                 *  
      33. 33.                 * @see java.lang.Object#toString()  
      34. 34.                 */  
      35. 35.                public String toString() {   
      36. 36.                    StringWriter sw = new StringWriter();   
      37. 37.                    writeTo(sw);   
      38. 38.                    return sw.toString();   
      39. 39.                }   
      40. 40.            };   
      41. 41.        }   
      42. 42.}  
      43. private static class SimpleTemplate implements Template {

      44.         protected Script script;

      45.         public Writable make() {
      46.             return make(null);
      47.         }

      48.         public Writable make(final Map map) {
      49.             return new Writable() {
      50.                 /**
      51.                  * Write the template document with the set binding applied to the writer.
      52.                  *
      53.                  * @see groovy.lang.Writable#writeTo(java.io.Writer)
      54.                  */
      55.                 public Writer writeTo(Writer writer) {
      56.                     Binding binding;
      57.                     if (map == null)
      58.                         binding = new Binding();
      59.                     else
      60.                         binding = new Binding(map);
      61.                     Script scriptObject = InvokerHelper.createScript(script.getClass(), binding);
      62.                     PrintWriter pw = new PrintWriter(writer);
      63.                     scriptObject.setProperty("out", pw);
      64.                     scriptObject.run();
      65.                     pw.flush();
      66.                     return writer;
      67.                 }

      68.                 /**
      69.                  * Convert the template and binding into a result String.
      70.                  *
      71.                  * @see java.lang.Object#toString()
      72.                  */
      73.                 public String toString() {
      74.                     StringWriter sw = new StringWriter();
      75.                     writeTo(sw);
      76.                     return sw.toString();
      77.                 }
      78.             };
      79.         }
      80. }
      復(fù)制代碼
      很清楚了,調(diào)用make方法,創(chuàng)建一個(gè)Script對(duì)象,綁定參數(shù)binding = new Binding(map)。 
      創(chuàng)建一個(gè)PrintWriter,綁定為out參數(shù),而模板解析的代碼中的out.print(內(nèi)容)就有著落了。 

      所以: 

      ?Groovy的模板是通過(guò)編譯,生成Java類,然后調(diào)用方法實(shí)現(xiàn)的 
      ?使用模板機(jī)制注意要緩存Script對(duì)象或Template對(duì)象,否則每次調(diào)用都會(huì)編譯生成一個(gè)新的Java類,導(dǎo)致內(nèi)存溢出/泄露

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多