iamhuzl

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            1 隨筆 :: 13 文章 :: 21 評論 :: 0 Trackbacks
          groovy的SimpleTemplateEngine實現了模板功能,類似于jsp。那就分析groovy是如何實現模板的。

          使用模板
          Template template = new SimpleTemplateEngine().createTemplate(
                  new StringReader("<% // This is a comment that will be filtered from output %>\n" +
                  "Hello <%out.println(name);%> !")
              );
          
              final StringWriter sw = new StringWriter();
              template.make([name:'bloodwolf_china').writeTo(sw);
              println sw.toString();
          


          看看SimpleTemplateEngine類
          public Template createTemplate(Reader reader) throws CompilationFailedException, IOException {
                  SimpleTemplate template = new SimpleTemplate();
                  String script = template.parse(reader);
                        
                      template.script = groovyShell.parse(script, "SimpleTemplateScript" + counter++ + ".groovy");
                 
                  return template;
              }
          
          

          這兒做了三件事
          1、創建了一個SimpleTemplate對象
          2、解析模板,主要是把<%=exp%>轉為groovy的內置表達式${exp},把非<%code%>轉為調用out.print(內容)函數,<%code%>中的就是groovy代碼了。這樣就把整個模板解析為一段代碼。如
          引用
          Hello <%out.println(name);%> !
          變成
          out.print("Hello ");
          out.println(name);
          out.print(" !");
          

          3、用groovyShell獲取一個Script對象

          Script對象只一個支持普通groovy對象,利用了Groovy的特性
          實現 getProperty(String property)方法,從參數綁定對象中獲取屬性,這樣腳本中就能獲取綁定參數。
          public abstract class Script extends GroovyObjectSupport {
              private Binding binding;
              public Object getProperty(String property) {
                  try {
                      return binding.getVariable(property);
                  } catch (MissingPropertyException e) {
                      return super.getProperty(property);
                  }
              }
               public abstract Object run();
          }
          

          groovyShell把一段代碼組裝成一個GroovyCodeSource對象,然后調用GroovyClassLoader,CompilationUnit把CodeSource編譯成一個Script對象,run()方法中執行的即是out.print(模板內容)這段代碼。

          在看看如何輸出模板內容的
          private static class SimpleTemplate implements Template {
          
                  protected Script script;
          
                  public Writable make() {
                      return make(null);
                  }
          
                  public Writable make(final Map map) {
                      return new Writable() {
                          /**
                           * Write the template document with the set binding applied to the writer.
                           *
                           * @see groovy.lang.Writable#writeTo(java.io.Writer)
                           */
                          public Writer writeTo(Writer writer) {
                              Binding binding;
                              if (map == null)
                                  binding = new Binding();
                              else
                                  binding = new Binding(map);
                              Script scriptObject = InvokerHelper.createScript(script.getClass(), binding);
                              PrintWriter pw = new PrintWriter(writer);
                              scriptObject.setProperty("out", pw);
                              scriptObject.run();
                              pw.flush();
                              return writer;
                          }
          
                          /**
                           * Convert the template and binding into a result String.
                           *
                           * @see java.lang.Object#toString()
                           */
                          public String toString() {
                              StringWriter sw = new StringWriter();
                              writeTo(sw);
                              return sw.toString();
                          }
                      };
                  }
          }
          

          很清楚了,調用make方法,創建一個Script對象,綁定參數binding = new Binding(map)。
          創建一個PrintWriter,綁定為out參數,而模板解析的代碼中的out.print(內容)就有著落了。

          所以:
          • Groovy的模板是通過編譯,生成Java類,然后調用方法實現的
          • 使用模板機制注意要緩存Script對象或Template對象,否則每次調用都會編譯生成一個新的Java類,導致內存溢出/泄露


          已有 0 人發表留言,猛擊->>這里<<-參與討論


          ITeye推薦



          posted on 2012-01-19 15:29 溫水青蛙 閱讀(1471) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 黑水县| 麻城市| 岫岩| 云南省| 七台河市| 五原县| 中山市| 清丰县| 舞阳县| 蓝山县| 思茅市| 长岛县| 界首市| 昂仁县| 海宁市| 连南| 惠州市| 房山区| 密山市| 洛隆县| 乌兰浩特市| 鄂温| 永康市| 开封市| 桂平市| 铜川市| 南涧| 大兴区| 顺义区| 大同市| 介休市| 故城县| 呼图壁县| 那曲县| 黄浦区| 永兴县| 巫山县| 宜昌市| 天门市| 安达市| 甘孜|