一.什么是代理模式
为其他对象提供一种代理提供功能,以控制对这个接口的访问,是一种结构性设计模式。
二.怎么写代理模式
我们来看看代理模式的UML类图
是不是感觉和装饰器模式有点像,不过代理模式更加注重的是对对象访问的控制,而装饰器模式的结构更多的是通过组合对象的方式对对象的进行扩展,要解决的问题不一样哈。
贴一下上面的代理模式的基本代码:
public interface Subject {
void request();
}
public class RealSubject extends Subject{
@Override
protected void request() {
System.out.println("real do sth");
}
}
public class MyProxy implements Subject {
private RealSubject realSubject;
@Override
public void request() {
if(realSubject==null) {
realSubject=new RealSubject();
}
realSubject.request();
}
}
public class Client {
public static void main(String[] args) {
Proxy proxy=new Proxy();
proxy.request();
}
}
以上就是静态代理的部分,除了这种还有动态代理,动态代理所实现的功能与静态代理一样,不一样的地方在于静态代理在代码编译的时候关系就已经确定了,.class文件已经生成完毕,而动态代理却是在程序运行的期间动态生成.class字节码文件。 动态代理怎么玩?我们需要借助于InvocationHandler 这个接口,使用 Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)去生成一个被代理的对象,便可实现动态代理。代码这么写呢,首先我们的代理类要实现InvocationHandle这个接口,重写invoke这个方法:
public class DProxy implements InvocationHandler {
private Object target; // 需要代理的对象
public DProxy(Object target) {
this.target = target;
}
/**
* proxy 代理类的实例
* method 被调用的方法
* args 方法参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法执行前可以加任意动作");
Object invoke = method.invoke(target, args);
System.out.println("方法执行后可以加任意动作");
return invoke;//返回被拦截方法,需要调用地方
}
}
这个invoke里面可以加任意你想做的事情,可以判断方法名等加一些你想做的事情,感觉ASPECJ也是可以这样玩,这里写完了,在使用的时候怎么去调用呢?请看代码:
public class Client {
public static void main(String[] args) {
Subject realSubject = new RealSubject();
Class<?> realClass = realSubject.getClass(); // 获取需要被代理的对象的Class 对象
InvocationHandler in = new DProxy(realSubject);
Subject subject=(Subject)Proxy.newProxyInstance(realClass.getClassLoader(), realClass.getInterfaces(), in);
//通过代理类对象调用代理类方法,实际上会转到invoke方法调用
subject.request();
}
}
这样就完成了动态代理了
三.小结
以上就是代理模式的内容,代理模式的好处就是解除了客户端和委托类的之间的耦合性,代理类可以在不修改委托类的情况下,在代理类增加一些其他行为。如果您觉得本文对您有所帮助,欢迎点赞或留下评论,如果觉得本文还要不足之处,也欢迎您在下方吐槽,谢谢!