我在我的程序中使用GroovyShell作为“表达式计算器/引擎”。它接受两个输入:(a)一个或多个init脚本(b)用户定义的脚本。然后,在运行时将两者作为大块脚本(文本)连接起来,并提供给shell。
String initScripts = getFromDB()
String userScript = getFromUser()
def shell = new GroovyShell()
output = shell.evaluate(initScripts + userScript)上面的代码将在一个循环中运行,其中userScript的内容将有所不同。
到目前为止,initScripts只包含可能在userScript (例如print "$yyyy 001")中引用的变量定义(例如def $yyyy = new Date().format('yyyy'))。
有没有更有效的方法来解决这个问题?(例如,重用外壳,如何重用?)因为现在进展很慢。
编辑: Groovy是必需的。请不要推荐其他脚本引擎。
编辑:,我在想GroovyShell是否能做到这一点(伪代码):
def shell = new GroovyShell()
shell.evaluate(initScripts)
for each userScript in DB {
shell.put(userScript )
def result = shell.evaluateThat()
println "Result is $result"
}这个是可能的吗?(上次我在谷歌上搜索是不可能的,但我希望我错了)
发布于 2011-03-16 19:25:03
您可以缓存GroovyShell,不需要总是创建一个新的:
final static GroovyShell shell = new GroovyShell()另外,如果您多次运行一个脚本,您也可以缓存它们。您可以用Script创建一个GroovyShell.parse(字符串scriptText),使用Script.run()运行脚本。
文档的这一节也可能有所帮助,而不是脚本,您也可以动态创建groovy对象。
发布于 2011-03-16 09:29:40
我想您可以避免每次构建一个完整的groovy环境所带来的负担。
从Java 6开始,Java中就有一个脚本API支持,它允许您使用轻量级脚本引擎。
作为示例,请参阅这个页面在groovy网站上解释如何使用GroovyScriptEngineImpl在Java应用程序中启动groovy脚本。
请注意,您可能会失去一些漂亮的优点,比如groovy葡萄,但是您可以
编辑需要注意的一点是,GroovyScriptEngineImpl和GroovyShell都不能保证任何类型的线程安全,因为任何groovy脚本都可以自由生成任意数量的线程。事实上,保护线程安全的唯一方法是通过安装SecurityManager禁止线程操作。事实上,即使这样也不能保证线程安全(因为这种线程安全只能通过确保所有Java代码库都是线程安全来实现)。
发布于 2011-03-17 06:09:26
最后我做了这个:
def shell = new GroovyShell()
shell.evaluate(initScripts)
for( i in 1..count )
{
output = shell.evaluate(userScripts);
}为了安全起见,您可以将shell放在ThreadLocal或池中。
https://stackoverflow.com/questions/5323114
复制相似问题