Java 代理模式 Proxy
简述:提供了对目标对象的间接访问方式,即通过代理访问目标对象.
目的:为其他对象提供一个代理以控制对某个对象的访问。
作用:
1.通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,
同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性。(解耦)
2.可以实现拦截方法,修改原方法的参数和返回值,满足了代理自身需求和目的,也就是是代理的方法增强性。(高扩展性)
代理类:负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。
图解:
静态代理:
–公共接口(抽象角色)
public interface Subject {
void vist();
}
–实际对象 (被代理对象)
public class RealSubject implements Subject{
private String name = "我是真实对象";
public void vist() {
System.out.println(name);
}
}
–代理对象
public class ProxySubject implements Subject{
private Subject subject;//接口
public ProxySubject(Subject subject) {
this.subject = subject; //这里初始化了,发现木有!相当于传入的 被代理对象,
//实现的是 被代理对象的方法,因为 实际对象也实现了公共接口!
}
public void vist() {
System.out.println("我是一号代理----");
subject.vist();
}
}
–客户端 测试
public class Client {
public static void main(String[] args) {
ProxySubject p = new ProxySubject(new RealSubject()); //看这,构造方法里面放的是 真实对象!
p.vist(); //然而这个p 确是 代理对象实例,由代理对象执行的 .vist() 方法!
}
}
控制台输出:
动态代理:
公共接口,实际对象,不变! 只是代理类变了.
由于运用的反射,所有在运行实,才知道被代理的对象.
–代理类:
public class DynamicProxy implements InvocationHandler{
//(JDK)java.lang.reflect.InvocationHandler:这是调用处理器接口,
//它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,
//通常在该方法中实现对委托类的代理访问。
private Object object;
public DynamicProxy(Object object){
this.object=object;
}
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
Object result =method.invoke(object, args); //前面说的反射中的,方法调用. invoke(对象,方法参数)
return result;
}
}
–客户端 测试
public class ProxyClient {
public static void main(String[] args) {
Subject relSubject = new RealSubject();
DynamicProxy proxy = new DynamicProxy(relSubject);//放入真实对象
ClassLoader classLoader = relSubject.getClass().getClassLoader();//获取真实对象的类加载器
Subject subject = (Subject) Proxy.newProxyInstance(classLoader, new Class[]{Subject.class}, proxy);
subject.vist();
}
}
静态代理,问题解析:
- 增加了代码维护的复杂度。
2.代理的对象过多,代理的方法不同就会出现毛病!
就像这样:
图片来自大佬:https://blog.csdn.net/WangQYoho/article/details/77584832
3.在编译器就已经确定被代理的对象
动态代理,问题解析:
–优点
- 在运行时,通过反射机制实现动态代理,并且能够代理各种类型的对象。
- 实现无侵入式的代码扩展。