我有一个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();
});
是否有实现的委托方法的直接方法调用一个更好的办法?