我有一個Java應用程序,我想添加一個擴展來執行groovy腳本。到目前爲止,解析,編譯和執行都不是問題!處理多個代表
爲簡化起見,我希望Groovy語法儘可能簡單(例如,不需要OO技能)。此外,groovy腳本應能夠訪問由java類初始化的庫函數。這是@Delegate
發揮作用的部分!
目前,我有兩個不同的解決方案,都不能完全令人滿意,我想出了:
GroovyService.java
public interface GroovyService { }
MyService.java
public class MyService implements GroovyService {
public static final MyService INSTANCE = new MyService();
private MyService() { /* ... */ }
public void method1() { /* ... */ }
public void method2() { /* ... */ }
}
解決方案#1 - 對於每個委託方法定義一個方法d快捷
ServicesFacade.java
public class ServicesFacade {
public static final ServicesFacade INSTANCE = new ServicesFacade();
@Delegate MyService myService;
// Further @Delegate of services ...
private ServicesFacade() {
myService = MyService.INSTANCE;
}
}
GroovyScript.groovy
def method1 = myService.&method1
def method2 = myService.&method2
if (method1()) {
method2()
}
的碼部分與方法的快捷方式可被預先考慮從常規文件讀取的字符串結果內容。如果沒有捷徑,它可以滿足我的期望,但我正在尋找一種解決方案,我不必跟蹤所有快捷方式。
解決方案2 - 使用的服務類型的列表和方法通配符訪問
ServicesFacade.java
public class ServicesFacade {
public static final ServicesFacade INSTANCE = new ServicesFacade();
@Delegate private final List<GroovyService> services = new ArrayList<>();
private ServicesFacade() {
this.services.add(MyService.INSTANCE);
}
public void addService(GroovyService service) {
this.services.add(service);
}
}
GroovyScript.groovy
if (services*.method1()) {
services*.method2()
}
這種解決方案的優點是我可以爲任何服務(服務*)使用固定的成員名稱,但我對語法印象不深。
Groovy的腳本的用法如下:
CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
compilerConfiguration.setScriptBaseClass(DelegatingScript.class.getName());
GroovyShell groovyShell = new GroovyShell(compilerConfiguration);
DelegatingScript script = (DelegatingScript) groovyShell.parse(fileContent);
if (script != null) {
script.setDelegate(ServicesFacade.INSTANCE);
scripts.add(script);
}
/* ... */
scripts.forEach(s -> {
s.run();
});
是否有實現的委託方法的直接方法調用一個更好的辦法?