Java 处理多个代理
我有一个java应用程序,我想为它添加一个扩展来执行groovy脚本。到目前为止,解析、编译和执行都不是问题 出于简化的原因,我希望groovy语法尽可能简单(例如,不需要OO技能)。此外,groovy脚本应该能够访问由java类初始化的库函数。这是Java 处理多个代理,java,groovy,delegates,Java,Groovy,Delegates,我有一个java应用程序,我想为它添加一个扩展来执行groovy脚本。到目前为止,解析、编译和执行都不是问题 出于简化的原因,我希望groovy语法尽可能简单(例如,不需要OO技能)。此外,groovy脚本应该能够访问由java类初始化的库函数。这是@代理发挥作用的部分 目前,我提出了两种不同的解决方案,但并不完全满足于我: GroovyService.java MyService.java 解决方案#1-为每个委托方法定义一个方法快捷方式 ServicesFacade.java GroovyS
@代理
发挥作用的部分
目前,我提出了两种不同的解决方案,但并不完全满足于我:
GroovyService.java
MyService.java
解决方案#1-为每个委托方法定义一个方法快捷方式
ServicesFacade.java
GroovyScript.groovy
带有方法快捷方式的代码部分可以在从groovy文件内容读取的字符串结果之前。如果没有捷径,它将满足我的期望,但我正在寻找一个解决方案,我不必跟踪所有的捷径
解决方案#2-使用服务类型和方法通配符访问列表
ServicesFacade.java
此解决方案的优点是,我可以为任何服务(services*)使用固定的成员名称,但我对其语法印象不深
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();
});
import groovy.lang.Binding;
import groovy.lang.MetaClass;
import groovy.lang.MissingMethodException;
import org.codehaus.groovy.runtime.InvokerHelper;
import java.util.HashMap;
import java.util.Map;
public abstract class MultiDelegatingScript extends groovy.lang.Script {
private final Map<Object, MetaClass> delegateMap = new HashMap<>();
protected MultiDelegatingScript() {
super();
}
protected MultiDelegatingScript(Binding binding) {
super(binding);
}
public void setDelegate(Object delegate) {
this.delegateMap.put(delegate, InvokerHelper.getMetaClass(delegate.getClass()));
}
@Override
public Object invokeMethod(String name, Object args) {
for (Map.Entry<Object, MetaClass> delegate : this.delegateMap.entrySet()) {
try {
// Try to invoke the delegating method
return delegate.getValue().invokeMethod(delegate.getKey(), name, args);
} catch (MissingMethodException mme) {
// Method not found in delegating object -> try the next one
continue;
}
}
// No delegating method found -> invoke super class method for further handling
return super.invokeMethod(name, args);
}
}
有没有更好的方法来实现委托方法的直接方法调用?我提出了一个很好的解决方案,其中我编写了一个类似于的类。情况如下:
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();
});
import groovy.lang.Binding;
import groovy.lang.MetaClass;
import groovy.lang.MissingMethodException;
import org.codehaus.groovy.runtime.InvokerHelper;
import java.util.HashMap;
import java.util.Map;
public abstract class MultiDelegatingScript extends groovy.lang.Script {
private final Map<Object, MetaClass> delegateMap = new HashMap<>();
protected MultiDelegatingScript() {
super();
}
protected MultiDelegatingScript(Binding binding) {
super(binding);
}
public void setDelegate(Object delegate) {
this.delegateMap.put(delegate, InvokerHelper.getMetaClass(delegate.getClass()));
}
@Override
public Object invokeMethod(String name, Object args) {
for (Map.Entry<Object, MetaClass> delegate : this.delegateMap.entrySet()) {
try {
// Try to invoke the delegating method
return delegate.getValue().invokeMethod(delegate.getKey(), name, args);
} catch (MissingMethodException mme) {
// Method not found in delegating object -> try the next one
continue;
}
}
// No delegating method found -> invoke super class method for further handling
return super.invokeMethod(name, args);
}
}
导入groovy.lang.Binding;
导入groovy.lang.MetaClass;
导入groovy.lang.MissingMethodException;
导入org.codehaus.groovy.runtime.InvokerHelper;
导入java.util.HashMap;
导入java.util.Map;
公共抽象类MultiDelegatingScript扩展了groovy.lang.Script{
私有最终映射delegateMap=newhashmap();
受保护的MultiDelegatingScript(){
超级();
}
受保护的MultiDelegatingScript(绑定){
超级(绑定);
}
公共无效集合委托(对象委托){
this.delegateMap.put(委托,InvokerHelper.getMetaClass(delegate.getClass());
}
@凌驾
公共对象调用方法(字符串名称、对象参数){
对于(Map.Entry委托:this.delegateMap.entrySet()){
试一试{
//尝试调用委派方法
返回delegate.getValue().invokeMethod(delegate.getKey(),name,args);
}捕获(丢失方法异常mme){
//在委派对象->尝试下一个中找不到方法
继续;
}
}
//找不到委派方法->调用超类方法进行进一步处理
返回super.invokeMethod(名称、参数);
}
}
使用这个类而不是DelegatingScript将完全满足我的期望
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);
}
}
if (services*.method1()) {
services*.method2()
}
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();
});
import groovy.lang.Binding;
import groovy.lang.MetaClass;
import groovy.lang.MissingMethodException;
import org.codehaus.groovy.runtime.InvokerHelper;
import java.util.HashMap;
import java.util.Map;
public abstract class MultiDelegatingScript extends groovy.lang.Script {
private final Map<Object, MetaClass> delegateMap = new HashMap<>();
protected MultiDelegatingScript() {
super();
}
protected MultiDelegatingScript(Binding binding) {
super(binding);
}
public void setDelegate(Object delegate) {
this.delegateMap.put(delegate, InvokerHelper.getMetaClass(delegate.getClass()));
}
@Override
public Object invokeMethod(String name, Object args) {
for (Map.Entry<Object, MetaClass> delegate : this.delegateMap.entrySet()) {
try {
// Try to invoke the delegating method
return delegate.getValue().invokeMethod(delegate.getKey(), name, args);
} catch (MissingMethodException mme) {
// Method not found in delegating object -> try the next one
continue;
}
}
// No delegating method found -> invoke super class method for further handling
return super.invokeMethod(name, args);
}
}