1. 代理模式的原理,其实就是类的组合,静态代理和动态代理都是一样的。
2. 代理一般可以用2种方式,一是继承, 二是组合
2.1 方式一
class A {
void a() {}
}
class B extend A {
void a() {
// 前面的处理
super.a();
// 后面的处理
}
}
2.2 方式二
class A {
void a() {}
}
class B {
A a ;
void a() {
// 前面的处理
a.a();
// 后面的处理
}
}
方式二要比方式一好, 理由是继承的耦合度太高,不如一修改,如果被代理类变了,代理类立马要变
下面是例子
------------------------------------
1.抽象角色
声明真实对象和代理对象的共同接口(租房接口)
2.代理角色(中介 租房接口)
代理对象角色内部含有对象真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口,以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他操作(收点费用),相当于对真实对象进行封装
3.真实角色(房主 租房接口)
代理角色所代表的真实对象,是我们最终要引用的对象
静态代理缺点
1.真实的角色必须存在
2.一个真实的角色必须对应一个代理角色,如果大量使用会导致类急剧的膨胀
解决缺点采用动态代理
动态代理 一个proxy可以代理100个真实的对象
静态代理 100个proxy代理100个真实对象
-----------------------------------------------------
静态代理
// 抽象角色
public abstract class Subject {
public abstract void request();
}
// 代理角色
public class ProxySubject extends Subject {
private ReadSubject readSubject;
public void request() {
//加在前面的操作
this.preRequest();
if(null == readSubject){
readSubject = new ReadSubject();
}
//真正的对象(被代理对象的方法)
readSubject.request();
//加到后面的操作
this.postRequest();
}
private void postRequest(){
System.out.println("post request");
}
private void preRequest(){
System.out.println("pre request");
}
}
// 真实的角色
public class ReadSubject extends Subject {
public void request() {
System.out.println("From real subject");
}
}
// 客户端测试
public class Client {
public static void main(String[] args) {
Subject subject = new ProxySubject();
subject.request();
}
}
----------------------------------------
动态代理
// 抽象角色
public interface Subject {
public void request();
}
// 动态代理角色(万能代理)
public class DynamicSubject implements InvocationHandler {
private Object object;
public DynamicSubject(Object object){
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("before calling" + method);
method.invoke(object, args);
System.out.println("after calling" + method);
return null;
}
}
// 真实的角色
public class RealSubject implements Subject {
public void request() {
System.out.println("from real subject!");
}
}
// 客户端测试
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
InvocationHandler handler = new DynamicSubject(realSubject);
Class<?> classType = handler.getClass();
/**
*
* realSubject.getClass().getInterfaces() :得到真实角色实现的接口
* param1:classType.getClassLoader():类的加载器,随便什么类的加载器都是可以的
* handler:实现InvocationHandler的控制类,它来控制到底代理那个真实的角色,在handler中可以切换真实角色
*/
Subject subject = (Subject)Proxy.newProxyInstance(classType.getClassLoader(),
realSubject.getClass().getInterfaces(), handler);
/**
1.动态生成的实例
public class $Proxy0 implements Subject{
//实现方法
public void request() {
// 利用反射的机制,得到方法
Method method = Subject .getClass().getMethod();handler.invoke(this, method, 参数 );
}
}
*/
subject.request();
}
}