我已经解决了这个问题。希望获得银弹。
我有几个单身(~10),它们都有一些功能(每个约10个)。我的函数调用看起来像这样(他们应该这样)。 注意:大多数这些调用都是异步的,不会返回任何内容。只有少数是同步的
SingletonClassGorrilla.getInstance().methodSwim(swimmingPool, lifeJacket, whistle);
SingletonClassRacoon.getInstance().methodBark(thief, owner);
我需要将所有这些调用放在沙盒中:
Sandbox.runThisInSandboxMode(new Runnable{
@Override
public void run(){
SingletonClassGorrilla.getInstance().methodSwim(swimmingPool, lifeJacket, whistle);
}
});
由于他们被调用的地方数量巨大,我希望单身人士可以实现sandboxMode
。
可能的解决方案(但由于我必须像这样包装的函数数量不可行):
public class SingletonClassGorrilla{
public void methodSwim(WaterBody waterBody, Instrument instrument,
EmResponse emResponse){
Sandbox.runThisInSandboxMode(new Runnable{
@Override
public void run(){
methodSwim(swimmingPool, lifeJacket, whistle, true);
}
});
}
private void methodSwim(WaterBody waterBody, Instrument instrument,
EmResponse emResponse, boolean fromSandbox){
// Do your thang.
}
}
无论如何,通过使用语言中的反射/注释/任何其他东西,可以减少所需的更改量吗?
答案 0 :(得分:1)
您可以使用合适InvocationHandler
的{{3}}(但您必须为每个单身人士提取interface
)。免责声明:我还没有尝试过编译/运行此代码,但它应该给你一般的想法。如果您关心单身人士的返回值,则可能必须在沙盒界面中使用Callable
代替/ Runnable
。
public class SingletonGorilla implements GorillaInterface {
private static SingletonGorilla theRealGorilla;
public static GorillaInterface getInstance() {
//In reality, you'd want to store off the Proxy as well
return Proxy.newProxyInstance(SingletonGorilla.class.getClassLoader(), GorillaInterface.class, new SandboxingHandler());
}
private static class SandboxingHandler implements InvocationHandler () {
public Object invoke(Object proxy, Method method, Object[] args) {
return Sandbox.runInSandbox( new Runnable() {
public void run () {
method.invoke(proxy, args));
}
}
}
}
答案 1 :(得分:0)
我正在考虑以下几点: 首先,您需要为每个单身人士提供一个界面:
接口:
package org.test.proxywrapper;
public interface IGorilla {
public void methodSwim();
}
实施班级:
package org.test.proxywrapper;
public class Gorilla implements IGorilla{
public void methodSwim()
{
}
}
然后,实现一个InvocationHandler,它会对每次调用Gorilla方法时常见的代码进行分解:
package org.test.proxywrapper;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class WrapperInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
Sandbox.runThisInSandboxMode(new Runnable() {
@Override
public void run() {
Object params = new Object[0];
try {
arg1.invoke(arg0, new Object[]{});
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
});
// return something if you need to
return new Object();
}
}
此时,在应用程序/系统的中心位置,使用Proxy包装每个单例,并传递代理引用而不是原始包装对象:
package org.test.proxywrapper;
import java.lang.reflect.Proxy;
public class Main {
public static void main(String argv[])
{
WrapperInvocationHandler wrapperInvocationHandler = new WrapperInvocationHandler();
Class<?>[] implementedTypes = new Class<?>[1];
implementedTypes[0] = IGorilla.class;
IGorilla proxy = (IGorilla) Proxy.newProxyInstance(Main.class.getClassLoader(), implementedTypes, wrapperInvocationHandler);
proxy.methodSwim();
}
}
这个简单的例子按照我的预期编译和运行。 我在这里剪了一些角,跳过了getInstance方法等,但我想它会让我知道它是如何完成的。