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版获得许可的。有关详细信息,请参见许可证。