黑马程序员_代理模式

------------------------------android培训java培训期待与您交流! ----------------------------------------------------------------


Java允许我们从多种途径为一个class生成对应的Class object

需求:练习Class

 

publicclass ClassTest

{

   publicstaticvoid main(String[] args)

   {

      Class<?> classType = Child.class;

     

      System.out.println(classType);

     

      classType = classType.getSuperclass();//得到父类.

     

      System.out.println(classType);

     

      classType = classType.getSuperclass();

     

      System.out.println(classType);

     

      classType = classType.getSuperclass();

     

      System.out.println(classType);

   }

}

 

 

class Parent

{

  

}

 

class Child extends Parent

{

  

}

结果:

class com.demo.reflect.Child

class com.demo.reflect.Parent

class java.lang.Object

null

静态代理模式:

• 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。

• 在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用

 

• 代理模式一般涉及到的角色有

– 抽象角色:声明真实对象和代理对象的共同接口

– 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装

– 真实角色:代理角色所代表的真实对象,是我们最终要引用的对象

 

publicabstractclass Subject

{

   publicabstractvoid request();

}

 

 

publicclass RealSubject extends Subject

{

   publicvoid request()

   {

      System.out.println("From realsubject.");

   }

}

 

publicclass ProxySubject extends Subject

{

   private RealSubject realSubject; //代理角色内部引用了真实角色,必须有个成员变量.

  

   publicvoid request()

   {

      this.preRequest(); //在真实角色操作之前所附加的操作

     

      if(null == realSubject)

      {

         realSubject = new RealSubject();//必须先把真实对象生成出来

      }

     

      realSubject.request(); //真实角色所完成的事情

     

      this.postRequest(); //在真实角色操作之后所附加的操作

   }

  

   privatevoid preRequest()//收取中介费.

   {

      System.out.println("pre request");

   }

  

   privatevoid postRequest()

   {

      System.out.println("post request");

   }

}

 

 

publicclass Client //客户端测试一下.

{

   publicstaticvoid main(String[] args)

   {

      Subject subject = new ProxySubject();

     

      subject.request();//想要的是真实角色,但看不到真实角色,只能请求他们共有的方法.

   }

}

 

• 由以上代码可以看出,客户实际需要调用的是RealSubject类的request()方法,现在用ProxySubject来代理 RealSubject类,同样达到目的,同时还封装了其他方法(preRequest(),postRequest()),可以处理一些其他问题。

 

另外,如果要按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。(成员变量)是实际使用时,一个真实角色必须对应一个 代理角色,如果大量使用会导致类的急剧膨胀;此外,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决

 

 

动态代理模式:

需求:动态代理,真实的角色不一定存在.演示动态代理.

• Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类:

• (1)Interface InvocationHandler:该接口中仅定义了一个方法

– public object invoke(Object obj,Methodmethod, Object[] args)

• 在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。 这个抽象方法在代理类中动态实现。

• (2)Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容

• protected Proxy(InvocationHandler h):构造函数,用于给内部的h赋值。

• static Class getProxyClass (ClassLoaderloader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。

•static Object newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)

 

• 所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你

必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可

以把该class的实例当作这些interface中的任何一个来用。当然,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作

 

 

• 在使用动态代理类时,我们必须实现InvocationHandler接口,代码实现:

 

publicinterface Subject

{

   publicvoid request();

}

 

publicclass RealSubject implements Subject

{

   publicvoid request()

   {

      System.out.println("From realsubject!");

   }

 

}

 

publicclass VectorProxy implements InvocationHandler

{

   private Object proxyObj;

 

   public VectorProxy(Object obj)

   {

      this.proxyObj = obj;

   }

 

   publicstatic Object factory(Object obj)

   {

      Class<?> classType =obj.getClass();

 

      return Proxy.newProxyInstance(classType.getClassLoader(),classType

            .getInterfaces(), new VectorProxy(obj));

   }

 

   public Object invoke(Object proxy, Method method,Object[] args)

         throws Throwable

   {

      System.out.println("before calling: " + method);

 

      if (null != args)

      {

         for (Object obj : args)

         {

            System.out.println(obj);

         }

      }

 

      Object object = method.invoke(proxyObj, args);

 

      System.out.println("after calling: " + method);

 

      return object;

   }

 

   publicstaticvoid main(String[] args)

   {

      List v = (List) factory(new Vector());

 

      System.out.println(v.getClass().getName());

 

      v.add("New");

      v.add("York");

 

      System.out.println(v);

 

      v.remove(0);

      System.out.println(v);

 

   }

 

}

 

publicclass Client

{

   publicstaticvoid main(String[] args)

   {

      RealSubject realSubject = new RealSubject();

 

      InvocationHandler handler = new DynamicSubject(realSubject);

 

      Class<?> classType =handler.getClass();

 

      // 下面的代码一次性生成代理

 

      Subject subject = (Subject)Proxy.newProxyInstance(classType

            .getClassLoader(),realSubject.getClass().getInterfaces(),

            handler);

 

      subject.request();

 

      System.out.println(subject.getClass());

 

   }

}

 

 

• 通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需

要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系

• 动态代理是指客户通过代理类来调用其它对象的方法

• 动态代理使用场合:

• 调试

• 远程方法调用(RMI)

 

 

动态代理步骤:

 

1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法

2.创建被代理的类以及接口

3.通过Proxy的静态方法newProxyInstance(ClassLoader loader, Class[] interfaces,InvocationHandler h) 创建一个代理

4.通过代理调用方法

 

 

public classVectorProxy implements InvocationHandler

{

       private Object proxyObj;

 

       public VectorProxy(Object obj)

       {

              this.proxyObj = obj;

       }

 

       public static Object factory(Object obj)

       {

              Class<?> classType =obj.getClass();

 

              return Proxy.newProxyInstance(classType.getClassLoader(),

                            classType.getInterfaces(),new VectorProxy(obj));

       }

      

       public Object invoke(Object proxy, Methodmethod, Object[] args)

                     throws Throwable

       {

              System.out.println("beforecalling: " + method);

             

              if(null != args)

              {

                     for(Object obj : args)

                     {

                            System.out.println(obj);

                     }

              }

             

              Object object =method.invoke(proxyObj, args);

             

              System.out.println("aftercalling: " + method);

             

              return object;

       }

      

       public static void main(String[] args)

       {

              List v = (List)factory(newVector());

             

              System.out.println(v.getClass().getName());

             

              v.add("New");

              v.add("York");

             

              System.out.println(v);

             

              v.remove(0);

              System.out.println(v);

             

       }

}

 

 

 

-----------------------------android培训java培训期待与您交流!----详细请查看:http://edu.csdn.net/heima---------------


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值