我对这个问题有点纠结。希望能得到一颗银弹。
我有几个单子(~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.
}
}是否通过使用反射/注释/语言中的任何其他东西来减少所需的更改量?
发布于 2015-08-18 19:03:56
您可以使用带有适当InvocationHandler的InvocationHandler(尽管您必须为每个单身者提取一个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));
}
}
}
}发布于 2015-08-18 19:04:13
我正在考虑以下几点:首先,您需要为每个单身者提供一个接口:
接口:
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();
}
}此时,在应用程序/系统的中心位置,用代理包装每个单例,并传递代理引用,而不是原始包装的对象:
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方法等等,但是我想它给出了一个如何实现它的想法。
https://stackoverflow.com/questions/32079580
复制相似问题