Rocker是Java 8+優化的,靠近零拷貝渲染,快速的模板引擎,可生成靜態鍵入的普通Java對像模板,這些模板與您的項目的其餘部分一起編譯。在開發過程中,不再需要“熱身”時間,基於反射的邏輯緩慢或令人討厭的驚喜。
使用具有標準Java表達式的邏輯,迭代和值的標準Java表達式編寫模板。使用搖滾歌手的特惠?
用於無效評估的存在算子。所有的繁重工作都是由搖桿解析器在開發過程中完成的 - 這使運行時的依賴關係僅限於幾個課程。 Rocker將解析您的模板並生成有記錄的Java源文件(因此您可以輕鬆地檢查和了解其工作原理)。
包括以下功能:
?
存在操作員擴展語法以簡化零值處理。Fizzed,Inc。的項目(在Twitter上關注:@fizzed_inc)
開發和維護開源項目需要大量時間。如果您發現此項目有用或需要商業支持,我們很想聊天。給我們發送電子郵件至[email protected]
項目發起人可能包括以下好處:
根據以下模板基準,Rocker是明顯的贏家。 〜250%的速度比自由標記者快,同時還需要降低記憶的順序。
大多數模板用於網站,因此,這是一個快速示例,顯示了搖桿模板的工作方式,並且可以在渲染過程中互相呼叫。創建一個包含通用標頭和頁腳的模板以及身體含量的佔位符。創建模板src/main/java/views/main.rocker.html
@args (String title, RockerBody content)
< html >
< head >
< title > @title </ title >
</ head >
< body >
@content
</ body >
</ html >
我們實際計劃向用戶展示的模板將在公共/標題頁腳的上下文中渲染其內容。用Java術語,它傳遞了在另一個模板中執行的渲染代碼塊。創建模板src/main/java/views/index.rocker.html
@args (String message)
@views.main.template("Home") - > {
< h1 > Hello @message! </ h1 >
}
嘿, RockerBody content
論點呢?我們在語法讀數中更詳細地介紹了它,但是現在只了解它是唯一的特殊類型的參數,並指示搖滾樂手希望將“身體”傳遞給它。
搖桿解析器將為每個模板生成一個Java源文件。它們將是target/generated-sources/rocker/views/main.java
和target/generated-sources/rocker/views/index.java
。在您的應用程序中,您可以這樣渲染索引模板。
static public void main ( String [] args ) {
String output = views . index . template ( "World" )
. render ()
. toString ();
}
輸出將等於:
< html >
< head >
< title > Home </ title >
</ head >
< body >
< h1 > Hello World! </ h1 >
</ body >
</ html >
一旦您生成了Java源並在代碼中查看,就可以簡單地查看其工作原理。 views.index類創建一個視圖。模板實例並交出渲染 - 同時還通過自身的塊,當@content
時它會呈現。該語法與Java 8中的lambda定義是相同的(用Java 8的lambdas實施,Java 6/7的匿名內部類實施)。 Rocker在幕後做許多事情,以確保創建其他模板的模板共享相同的渲染上下文(輸出緩衝區,特定於應用程序的上下文/隱式狀態)。
查看語法文件,以便在搖滾語法上進行全面的深入研究。
Rocker擁有越來越多的框架清單,它們已與之無縫集成。如果要鏈接到添加的新框架,請提交問題或提交PR:
每個搖桿模板的靜態(純文本)(默認情況下)是內部存儲的,因為靜態字節陣列已經轉換為目標charset(例如UTF-8)。渲染模板時 - 靜態字節陣列將在所有請求中重複使用。搖桿渲染到一個優化的輸出流,該流將復合(鏈接的列表)的視圖(鏈接列表)的視圖以及您的動態內容。由於模板主要由一遍又一遍地呈現到同一字符的靜態內容組成,而不是分配新的內存,複製該內容,然後將其轉換為每個請求的目標charset - Rocker只是一遍又一遍地使用一個指針再次。該技術可產生快速,內存有效的渲染。
假設您有一個模板,該模板由9000個字節的普通靜態文本和1000個字節的動態內容組成。沒有此優化,將需要約100MB的內存才能服務10000請求(10000字節x 10000請求)。通過此優化,將需要〜10MB的內存才能服務10000請求(1000字節X 10000請求)。除了較低的內存外,您還切出90MB的內存副本和90MB的UTF-8字符串 - >字節轉換。一個非常有用的優化。
所有內容都是由您的項目編譯器和其他Java源代碼編譯的。模板中的任何動態代碼最終都會轉換為標準Java並編譯。未使用反射。
版本0.10.0在開發過程中引入了對熱裝加載模板的支持。熱加載使您可以修改模板源代碼,保存它,並在下一個請求上進行更改,而無需重新啟動JVM。 Rocker提供了兩種不同的熱重新加載風味,以靈活。
搖滾模板的主要功能是,您的模板是由Java編譯器檢查的使用,參數,邏輯等的編譯時間。
在0.10.0版本中,模板的基礎結構在模板生成兩個基礎類的情況下進行了修改。每個模板都會生成模型類(其接口)和一個實現類(其渲染器)。您的應用程序只會直接與模型進行交互,因此允許Rocker動態重新編譯並重新加載實現類。
風味的主要好處是,您的應用程序代碼保持不變,並且由Java編譯器檢查,而模板內容可以在運行時進行修改並自動重新加載。僅在您實際更改模板參數的情況下,您才需要重新啟動應用程序。
如果您喜歡完全動態模板的便利性,則味道兩個支持模板模型類(其接口)以及實現類(其渲染器)的熱重新加載。您的應用程序將失去一些編譯時間檢查,並且性能很小,但可以獲得所有可重新加載的便利。您的應用程序使用模板的方式也不同。
import com . fizzed . rocker . Rocker
...
// dynamic interfaces, dynamic implementation
String rendered = Rocker . template ( "views/index.rocker.html" )
. bind ( "val" , "ValueA" )
. render ()
. toString ();
模板路徑和參數將進行運行時檢查。請注意,每個可約束值必須與模板中聲明的名稱和類型匹配。
如果您的可綁定地圖可能包含的值比所需的值更多的值可用。如果屬性是所需列表的額外的,則放鬆的替代方案不會失敗。例如:
@args (String name)
Hello ${name}!
將在放鬆模式下呈現為:
Map map = new HashMap ();
map . put ( "name" , "Joe" );
map . put ( "age" , 42 );
Rocker . template ( "views/hello.rocker.html" )
. relaxedBind ( map )
. render ();
// -> Hello Joe!
默認情況下,在0.10.0版本中,默認情況下,將對熱裝加載的支持添加到生成的模板中。如果您想禁用支持,請設置配置/系統屬性rocker.optimize
。在構建過程中將其優化為true。由於默認情況下,由於模板中存在代碼,因此您只需要在運行時打開它。
需要將rocker-compiler
依賴性添加到您的構建中。這種依賴性只需要在開發過程中存在,並且可以在生產中刪除。在Maven中,這意味著您需要在provided
範圍中添加依賴關係。
< dependency >
< groupId >com.fizzed</ groupId >
< artifactId >rocker-compiler</ artifactId >
< version >2.1.0</ version >
< scope >provided</ scope >
</ dependency >
在運行時激活熱重加載。您可以使用系統屬性或編程性地激活HOT重新加載。用於使用Maven中的系統屬性激活熱加載。
mvn -Drocker.reloading=true ...rest of args...
另外,您可以通過編程方式激活熱加載。
import com . fizzed . rocker . runtime . RockerRuntime
...
RockerRuntime . getInstance (). setReloading ( true );
有一個簡單的示例,展示了動作中的熱裝。該項目使用Blaze來幫助腳本任務。運行以下內容
java -jar blaze.jar hot_reload
將瀏覽器指向http:// localhost:8080
然後,修改並保存rocker-test-reload/src/test/java/views/index.rocker.html
,然後刷新您的瀏覽器。
搖桿由兩個組件組成 - 解析器/發電機和運行時。要在項目中使用Rocker,請將運行時依賴性添加到您的應用程序中,然後在構建工具中啟用解析器,然後創建第一個模板。
Rocker出版給Maven Central。添加為Maven的依賴性:
< dependency >
< groupId >com.fizzed</ groupId >
< artifactId >rocker-runtime</ artifactId >
< version >2.1.0</ version >
</ dependency >
<!-- for hot-reloading support only during development -->
< dependency >
< groupId >com.fizzed</ groupId >
< artifactId >rocker-compiler</ artifactId >
< version >2.1.0</ version >
< scope >provided</ scope >
</ dependency >
添加為Gradle的依賴性:
repositories {
mavenCentral()
}
dependencies {
compile group : ' com.fizzed ' , name : ' rocker-runtime ' , version : ' 2.1.0 '
// add rocker-compiler dependency as needed
}
搖滾歌手支持Maven和Gradle開箱即用。
將以下內容添加到您的POM中
< build >
< plugins >
< plugin >
< groupId >com.fizzed</ groupId >
< artifactId >rocker-maven-plugin</ artifactId >
< version >2.1.0</ version >
< executions >
< execution >
< id >generate-rocker-templates</ id >
< phase >generate-sources</ phase >
< goals >
< goal >generate</ goal >
</ goals >
</ execution >
</ executions >
</ plugin >
</ plugins >
</ build >
默認情況下,Rocker將在src/main/java
中以.rocker.html
結尾的任何模板文件遞歸處理。保存模板的目錄將成為將生成的Java類放入的標準Java軟件包。生成的Java源文件將保存到target/generated-sources/rocker
。該插件將負責將此生成的目錄添加到您的源根。
支持以下屬性:
templateDirectory
是從定位和解析模板文件時遞歸啟動的基本目錄。 Java package
將生成模板將使用此目錄作為基礎。因此,如果您有${templateDirectory}/views/mytemplate.rocker.html
,那麼Rocker將生成${outputDirectory}/views/mytemplate.java
。默認為${project.build.sourceDirectory}
。
outputDirectory
是解析器將生成模板源的目錄。默認為${project.build.directory}/generated-sources/rocker
classDirectory
是Hot Reload功能將(重新)編譯為運行時的目錄。默認為${project.build.outputDirectory}
failOnError
確定是否有任何解析/生成錯誤會導致Maven失敗。默認為true。
skip
確定是否應跳過插件的執行。默認為false。
成功生成Java源後, touchFile
是“觸摸”的文件。對於觸發其他工作流程有用。除非明確告知重新加載或更改maven pom.xml文件,否則許多IDE不會自動重新加載代碼完成的來源以完成代碼。因此,默認情況下,此值設置為${basedir}/pom.xml
。保持啟用通常是無害的。
skipTouch
禁用觸摸file。默認為false。
addAsSources
將為Maven添加outputDirectory,作為要編譯的來源。默認為true。
addAsTestSources
將為MAVEN添加輸出指導,作為要編譯的測試源。默認為false。如果為true,則在附加庫之前對此進行評估,並有效地告訴Maven將模板編譯為測試代碼。
還支持以下屬性,但是重要的是要了解這些屬性本質上是對解析器的傳遞覆蓋,它們都默認為Rocker的默認值。
javaVersion
是您想要的模板和運行時與兼容的Java版本。默認為執行Maven的JVM的Java版本(例如“ 1.8”)。
optimize
確定是否將從生成的模板中刪除熱重載支持。默認情況下為fals。
extendsClass
是所有模板實現都應擴展的類。對於您希望所有模板擴展的特定於應用程序的中間類都有用。默認為Rocker的默認值。
extendsModelClass
是所有模板模型都應擴展的類。對於您希望所有模板模型擴展的特定於應用程序的中間類都很有用。默認為Rocker的默認值。
plainTextStrategy
是用於將純文本嵌入模板的一部分的策略。默認值為static_byte_arrays_via_unloaded_class,但是如果您需要graalvm兼容性,則可以嘗試static_byte_arrays
discardLogicWhitespace
確定是否應丟棄確定僅是邏輯/控制塊的一部分的模板中的空格。幫助使渲染的內容看起來更專業,同時仍然完整地保持您的格式。默認為Rocker的默認值。
targetCharset
是模板輸出的目標CHARSET。默認為Rocker的默認值。
suffixRegex
是用於查找模板解析的正則表達式。默認為Rocker的默認值。
markAsGenerated
向生成的類添加了@Gererated註釋。保留是類,以便僅依靠類文件而不是源代碼的工具使用註釋。默認為Rocker的默認值。
感謝@victory
和@mnlipp
貢獻Gradle插件。 @etiennestuder
還使用了您可能需要考慮的替代Gradle插件。 Rocker's Gradle插件已發佈到gradle.org。只需將以下內容添加到您的構建腳本:
plugins {
id " com.fizzed.rocker " version " 2.1.0 "
}
sourceSets {
main {
rocker {
srcDir( ' src/main/java ' )
}
}
}
rocker {
// (All settings are shown with their defaults)
//
// Skips building templates all together
skip false
// Base directory for generated java sources, actual target is sub directory
// with the name of the source set. The value is passed through project.file().
outputBaseDirectory = " $b uildDir /generated-src/rocker "
// Base directory for the directory where the hot reload feature
// will (re)compile classes to at runtime (and where `rocker-compiler.conf`
// is generated, which is used by RockerRuntime.getInstance().setReloading(true)).
// The actual target is a sub directory with the name of the source set.
// The value is passed through project.file().
classBaseDirectory = " $b uildDir /classes "
failOnError true
skipTouch true
// must not be empty when skipTouch is equal to false
touchFile " "
javaVersion ' 1.8 '
extendsClass null
extendsModelClass null
optimize null
discardLogicWhitespace null
targetCharset null
suffixRegex null
postProcessing null
markAsGenerated null
}
下面的詳細描述了模板語法,但現在創建一個新文件,以${templateDirectory}/views/HelloWorld.rocker.html
@*
Example of hello world
*@
@args (String message)
Hello @message!
是時候編譯您的項目並開始使用模板了。您可以從Java稱呼它:
static public void main ( String [] args ) {
String output = views . HelloWorld
. template ( "World" )
. render ()
. toString ();
}
搖桿(默認情況下)對搖桿進行了大量優化,以輸出模板作為字節數組。默認的RockerOutput
模板將呈現為類型com.fizzed.rocker.runtime.ArrayOfByteArraysOutput
。這是字節陣列或異步IO的絕佳選擇。但是,該框架具有優化字符串渲染(或其他自定義輸出)的功能。
有效地渲染到字符串:
import com . fizzed . rocker . runtime . StringBuilderOutput ;
static public void main ( String [] args ) {
StringBuilderOutput output = views . HelloWorld
. template ( "World" )
. render ( StringBuilderOutput . FACTORY );
String text = output . toString ();
}
有效地渲染到輸出流:
import com . fizzed . rocker . runtime . OutputStreamOutput ;
static public void main ( String [] args ) throws Exception {
final OutputStream os = new FileOutputStream ( new File ( "test" ));
OutputStreamOutput output = views . HelloWorld
. template ( "World" )
. render (( contentType , charsetName ) -> new OutputStreamOutput ( contentType , os , charsetName ));
}
請注意,如果在渲染過程中有例外,則輸出流將呈現一個部分模板(直到例外點)。在大多數情況下,最好將渲染到默認的com.fizzed.rocker.runtime.ArrayOfByteArraysOutput
,然後將其字節陣列的緩衝區直接寫入您的outputStream。
有許多搖滾歌手的演示。從解析模板到模型到異步在HTTP服務器中發送結果。該項目使用Blaze來幫助腳本任務。為完整列表運行以下內容:
java -jar blaze.jar -l
版權(C)2015+ Fizzed,Inc。
這項工作是根據Apache許可證的2.0版獲得許可的。有關詳細信息,請參見許可證。