groovy的SimpleTemplateEngine實現了模板功能,類似于jsp。那就分析groovy是如何實現模板的。
使用模板
看看SimpleTemplateEngine類
這兒做了三件事
1、創建了一個SimpleTemplate對象
2、解析模板,主要是把<%=exp%>轉為groovy的內置表達式${exp},把非<%code%>轉為調用out.print(內容)函數,<%code%>中的就是groovy代碼了。這樣就把整個模板解析為一段代碼。如
3、用groovyShell獲取一個Script對象
Script對象只一個支持普通groovy對象,利用了Groovy的特性
實現 getProperty(String property)方法,從參數綁定對象中獲取屬性,這樣腳本中就能獲取綁定參數。
groovyShell把一段代碼組裝成一個GroovyCodeSource對象,然后調用GroovyClassLoader,CompilationUnit把CodeSource編譯成一個Script對象,run()方法中執行的即是out.print(模板內容)這段代碼。
在看看如何輸出模板內容的
很清楚了,調用make方法,創建一個Script對象,綁定參數binding = new Binding(map)。
創建一個PrintWriter,綁定為out參數,而模板解析的代碼中的out.print(內容)就有著落了。
所以:
已有 0 人發表留言,猛擊->>這里<<-參與討論
ITeye推薦
使用模板
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推薦