现在的位置: 首页 > 综合 > 正文

代理模式proxy (静态代理、动态代理)

2018年02月04日 ⁄ 综合 ⁄ 共 2893字 ⁄ 字号 评论关闭

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个真实的对象

静态代理 100proxy代理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();
 }

}

 

 

 

 

抱歉!评论已关闭.