Vah*_*deh 3 grails groovy grails-plugin
我想在编译时修改一些Grails域类.我最初认为这是Groovy的全局ASTTransformation的工作,因为我不想注释我的域类(本地变换器需要).最好的方法是什么?
我也尝试通过在同一个包中创建我自己的类来模仿DefaultGrailsDomainClassInjector.java,实现相同的接口,但我可能只是不知道如何将它打包在正确的位置,因为我从未看到我的方法被调用.
另一方面,我能够手动创建一个包含已编译的AST转换类的JAR,以及纯Groovy全局转换所需的META-INF/services工件.我把JAR扔进了我的项目的"lib"目录,并成功调用了visit().显然这是一个草率的工作,因为我希望在Grails插件中获得我的AST转换的源代码,如果我不需要,则不需要单独的JAR工件,加上我无法通过拥有这种方法来实现我的Grails插件的"lib"中的JAR,但不得不将它放入Grails应用程序的"lib"中.
这篇文章也有所帮助:Grails 2.1.1 - 如何使用AstTransformer开发插件?
关于全局转换的事情,编译开始时应该可以使用转换代码.将变压器放在罐子里是我先做的!但正如你所说,这是一项草率的工作.你想要做的是让你的ast转换类在其他人进入编译阶段之前编译.这是你做的!
创建一个名为precompiledin srcfolder的目录!并使用正确的打包结构添加Transformation类和转换器在此目录中使用的类(如注释).
然后创建一个名为call org.codehaus.groovy.transform.ASTTransformationin 的文件precompiled/META-INF/services,您将拥有以下结构.
precompiled
--amanu
----LoggingASTTransformation.groovy
--META-INF
----services
------org.codehaus.groovy.transform.ASTTransformation
Run Code Online (Sandbox Code Playgroud)
然后在org.codehaus.groovy.transform.ASTTransformation文件中写入变换器的完全限定名称,对于上面的示例,将使用完全限定名称amanu.LoggingASTTransformation
package amanu
import org.codehaus.groovy.transform.GroovyASTTransformation
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.control.SourceUnit
@GroovyASTTransformation(phase=CompilePhase.CANONICALIZATION)
class TeamDomainASTTransformation implements ASTTransformation{
public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
println ("*********************** VISIT ************")
source.getAST()?.getClasses()?.each { classNode ->
//Class node is a class that is contained in the file being compiled
classNode.addProperty("filed", ClassNode.ACC_PUBLIC, new ClassNode(Class.forName("java.lang.String")), null, null, null)
}
}
}
Run Code Online (Sandbox Code Playgroud)
执行此操作后,您可以通过两种方式进行操作!第一种方法是将它放在罐子里,就像你一样!另一种是使用groovy脚本在其他人之前编译它.要在grails中执行此操作,我们使用_Events.groovy脚本.
你可以从插件或主项目中做到这一点,没关系.如果它不存在,请创建一个名为的文件_Events.groovy并添加以下内容.
代码从reinhard-seiler.blogspot.com复制并进行修改
eventCompileStart = {target ->
...
compileAST(pluginBasedir, classesDirPath)
...
}
def compileAST(def srcBaseDir, def destDir) {
ant.sequential {
echo "Precompiling AST Transformations ..."
echo "src ${srcBaseDir} ${destDir}"
path id: "grails.compile.classpath", compileClasspath
def classpathId = "grails.compile.classpath"
mkdir dir: destDir
groovyc(destdir: destDir,
srcDir: "$srcBaseDir/src/precompiled",
classpathref: classpathId,
stacktrace: "yes",
encoding: "UTF-8")
copy(toDir:"$destDir/META-INF"){
fileset(dir:"$srcBaseDir/src/precompiled/META-INF")
}
echo "done precompiling AST Transformations"
}
}
Run Code Online (Sandbox Code Playgroud)
之前的脚本将在编译其他脚本之前编译变换器!这使变换器可用于转换域类.
如果您使用除类路径中添加的类以外的任何类,则还必须预编译它们.上面的脚本将编译precompiled目录中的所有内容,您还可以添加不需要ast的类,但在该目录中需要它!
如果要在转换中使用域类,可能需要在evenCompileEnd块中进行预编译!但这会让事情变得更慢!
@Douglas Mendes提到有一种简单的方法可以导致预编译.哪个更简洁.
eventCompileStart = {
target -> projectCompiler.srcDirectories.add(0, "./src/precompiled")
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1729 次 |
| 最近记录: |