groovy java联合,避免跨不同的Groovy脚本共享Java元类

我的情况

我从Java调用多个Groovy脚本,它们都包含长期存在的Groovy对象 .

我希望我的Groovy脚本能够对Java类(具有大约100个实例)的Java元类进行一些更改 . 但是,脚本应该能够进行不同的更改,其中一个脚本中的更改不应该反映在其他脚本中 .

问题:Java类的元类在所有脚本中共享 .

示例代码

SameTest.java

public interface SameTest {

void print();

void addMyMeta(String name);

void addJavaMeta(String name);

void callMyMeta(String name);

void callJavaMeta(String name);

}

SameSame.java

import groovy.lang.Binding;

import groovy.util.GroovyScriptEngine;

public class SameSame {

public SameTest launchNew() {

try {

GroovyScriptEngine scriptEngine = new GroovyScriptEngine(new String[]{""});

Binding binding = new Binding();

binding.setVariable("objJava", this);

SameTest script = (SameTest) scriptEngine.run("test.groovy", binding);

return script;

} catch (Exception | AssertionError e) {

throw new RuntimeException(e);

}

}

public static void main(String[] args) {

SameSame obj = new SameSame();

SameTest a = obj.launchNew();

SameTest b = obj.launchNew();

a.addMyMeta("a");

a.callMyMeta("a");

try {

b.callMyMeta("a");

throw new AssertionError("Should never happen");

} catch (Exception ex) {

System.out.println("Exception caught: " + ex);

}

a.addJavaMeta("q");

b.callJavaMeta("q");

a.print();

b.print();

}

}

test.groovy

ExpandoMetaClass.enableGlobally()

class Test implements SameTest {

SameSame objJava

void print() {

println 'My meta class is ' + Test.metaClass

println 'Java meta is ' + SameSame.metaClass

}

void addMyMeta(String name) {

println "Adding to Groovy: $this $name"

this.metaClass."$name" << {

"$name works!"

}

}

void addJavaMeta(String name) {

println "Adding to Java: $this $name"

objJava.metaClass."$name" << {

"$name works!"

}

}

void callMyMeta(String name) {

println "Calling Groovy: $this $name..."

"$name"()

println "Calling Groovy: $this $name...DONE!"

}

void callJavaMeta(String name) {

println "Calling Java: $this $name..."

objJava."$name"()

println "Calling Java: $this $name...DONE!"

}

}

new Test(objJava: objJava)

Output

Adding to Groovy: Test@7ee955a8 a

Calling Groovy: Test@7ee955a8 a...

Calling Groovy: Test@7ee955a8 a...DONE!

Calling Groovy: Test@4a22f9e2 a...

Exception caught: groovy.lang.MissingMethodException: No signature of method: Test.a() is applicable for argument types: () values: []

Possible solutions: any(), any(groovy.lang.Closure), is(java.lang.Object), wait(), wait(long), each(groovy.lang.Closure)

Adding to Java: Test@7ee955a8 q

Calling Java: Test@4a22f9e2 q...

Calling Java: Test@4a22f9e2 q...DONE!

My meta class is groovy.lang.ExpandoMetaClass@2145b572[class Test]

Java meta is groovy.lang.ExpandoMetaClass@39529185[class SameSame]

My meta class is groovy.lang.ExpandoMetaClass@72f926e6[class Test]

Java meta is groovy.lang.ExpandoMetaClass@39529185[class SameSame]

期望的结果

显示有关Java元信息的两行应该是不同的 .

这应该崩溃:

a.addJavaMeta("q");

b.callJavaMeta("q");

这个问题

有可能以某种方式在不同的 GroovyScriptEngine 实例中使用不同的 MetaClassRegistry 吗?

或者是否有其他方法可以实现上述所需的结果?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值