2010-11-22 53 views
2

在我的應用程序中,我使用Groovy作爲腳本語言。爲了讓我的客戶更容易,我有一個全球範圍,我定義助手類和常量。在嵌入式groovy腳本中確定範圍

目前,我需要運行腳本(它建立了全球範圍內)在每次執行用戶腳本時間:

context = setupGroovy(); 
runScript(context, "global.groovy"); // Can I avoid doing this step every time? 
runScript(context, "user.groovy"); 

有沒有一種方法來設置這個全球範圍一次,只是告訴嵌入的腳本解釋者:「看這裏,如果你找不到變量」?這樣,我可以運行一次全局腳本。

注意:安全性在這裏不是問題,但如果您知道確保用戶無法修改全局範圍的方法,那是另外一個優點。

回答

1

一個簡單的解決方案是從​​使用代碼:您可以預編譯腳本,像這樣:

GroovyCodeSource gcs = AccessController.doPrivileged(new PrivilegedAction<GroovyCodeSource>() { 
     public GroovyCodeSource run() { 
      return new GroovyCodeSource(scriptCode, fileName, GroovyShell.DEFAULT_CODE_BASE); 
     } 
    }); 
    GroovyClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<GroovyClassLoader>() { 
     public GroovyClassLoader run() { 
      return new GroovyClassLoader(parentLoader, CompilerConfiguration.DEFAULT); 
     } 
    }); 
    Class<?> scriptClass = loader.parseClass(gcs, false); 

這是昂貴的部分。現在使用InvokeHelper將編譯的代碼綁定到上下文(使用全局變量)並運行它:

Binding context = new javax.script.Binding(); 
Script script = InvokerHelper.createScript(scriptClass, context); 
script.run(); 
1

從groovy.codehaus無恥被盜:

誰想要Groovy腳本嵌入到 他們的服務器,並讓它們在修改時重新加載 人 最完整的解決方案是 的GroovyScriptEngine。您可以使用一組 CLASSPATH(例如可以是URL 或目錄名稱的根)初始化 GroovyScriptEngine。然後您可以在 根內執行任何Groovy腳本。 GSE還將跟蹤腳本之間的 依賴關係,以便 (如果有任何相關腳本被修改) 整個樹將被重新編譯並且 被重新加載。

此外,每次運行一個腳本 您可以在綁定該 包含腳本 可訪問性傳遞。在腳本運行後,在 腳本中設置的任何屬性也將在該綁定中可用 。這裏 是一個簡單的例子:

/my/groovy/script/path/hello.groovy: 

output = "Hello, ${input}!" 
import groovy.lang.Binding; 
import groovy.util.GroovyScriptEngine; 

String[] roots = new String[] { "/my/groovy/script/path" }; 
GroovyScriptEngine gse = new GroovyScriptEngine(roots); 
Binding binding = new Binding(); 
binding.setVariable("input", "world"); 
gse.run("hello.groovy", binding); 
System.out.println(binding.getVariable("output")); 
This will print "Hello, world!". 

發現:here

會像你的工作?