动态代理适用场景
需要统一入口调用
python动态代理的原理
类似于装饰器的闭包调用方法, 这与python的反射
python动态代理方案
在Python里面类的属性(方法)都是一个对象,我们先拿到这个类方法对象attr,然后对这个类方法对象进行包装,再返回包装后的新方法对象newAttr。
注意在获取target对象时,不能直接使用self.target,因为self.target会再次调用getattribute方法,这样就会导致死循环致堆栈过深曝出异常。取而代之应该使用object.getattribute方法来获取对象的属性值。
python动态代理代码
class Proxy:
def __init__(self, target):
self.target = target
def __getattribute__(self, item):
target = object.__getattribute__(self, "target")
attr = object.__getattribute__(target, item)
def new_attr(*args, **kwargs):
return attr(*args, **kwargs)
return new_attr
class Hello:
def __init__(self, test):
self.test = test
def prints(self):
print(self.test)
def t2():
print("t2")
h = Hello("test")
p = Proxy(h)
p.prints()
image.png
java动态代理代码
import java.lang.reflect.Method;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
class RealHello {
public void say(String s) {
System.out.println("hello " + s);
}
}
class HelloDelegate<T> implements MethodHandler {
private T target;
public HelloDelegate(T target) {
this.target = target;
}
@Override
public Object invoke(Object self, Method method, Method proceed, Object[] args) throws Throwable {
System.out.println("before print");
method.invoke(target, args);
System.out.println("after print");
return null;
}
}
public class DynamicProxy {
public static void main(String[] args) {
RealHello hello = enhanceHello(new RealHello());
hello.say("world");
}
@SuppressWarnings("unchecked")
public static <T> T enhanceHello(T target) {
ProxyFactory proxy = new ProxyFactory();
proxy.setSuperclass(RealHello.class);
try {
HelloDelegate<T> delegate = new HelloDelegate<T>(target);
// create方法传递了两个空数组
// 分别代表构造器的参数类型数组和构造器的参数实例数组
return (T) proxy.create(new Class<?>[0], new Object[0], delegate);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
网友评论