黑马程序员—动态代理模式

本文介绍了Java中的动态代理模式,重点讲解了Proxy类的构造函数和getProxyClass方法,这两个核心组成部分帮助我们创建并获取代理类,从而实现对真实类的代理操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

1.概念:
(1).JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理。
(2).JVM生成的动态代理类必须实现一个或多个接口。所以,JVM生成的动态类只能用作具有相同接口的目标类的实现类。
(3).CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理。所以,如果要为一个没有实现接口的类生成动态代理类,那么可以用CGLIB库。
(4).代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理类中的如下四个位置加上系统功能代码:
a.在调用目标方法之前;
b.在调用目标方法之后;
c.在调用目标方法前后;
c.在处理目标方法异常的catch块中;

2.一般主要涉及到以下两个类 : 
(1). Interface InvocationHandler :该接口中仅定义了一个方法 Object invoke(Object obj,Method method, Object[] args) 。在实际使用时,第一个参数 obj 一般是指代理类, method 是被代理的方法 args 为该方法的参数数组。这个抽象方法在代理类中动态实现。 

(2).Proxy:该类即为动态代理类,其中主要包含以下内容: 

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

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

Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) :返回代理类的一个实例,返回后的代理类可以当作被代理类使用 。 

3. 所谓 Dynamic Proxy 是这样一种 class :它是在运行时生成的 class ,在生成它时你必须提供一组 interface 给它,然后该 class 就宣称它实现了这些 interface 。你当然可以把该 class 的实例当作这些 interface 中的任何一个来用。当然啦,这个 Dynamic Proxy 其实就是一个 Proxy ,它不会替你作实质性的工作,在生成它的实例时你必须提供一个 handler ,由它接管实际的工作。

4.创建动态代理的步骤
(1).创建一个实现接口InvocationHandler的类,它必须实现invoke方法;
(2).创建被代理的类以及接口;
(3).通过Proxy的静态方法:newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)创建一个代理;
(4).通过代理调用方法;

例子:
抽象角色
package  com.nan.proxi;
public  interface  Subject {
      public  void  request();
}

代理角色
/*
 * 该代理类的内部属性是Object类型,实际使用的时候通过该类的构造方法传递进来一个对象;
 * 此外,该类还实现了invoke方法,该方法中method.invoke其实就是调用被代理对象的将要执行的方法,
 * 方法参数是sub,表示该方法从属于sub。通过动态代理类,我们可以在执行真实对象的方法的前后写上自己
 * 额外的方法
 */
public  class  ProSubject  implements  InvocationHandler {
      private  Object  sub  =  null ;
      public  ProSubject(Object obj){
             this .  sub  = obj;
     }
     
      @Override
      public  Object invoke(Object proxy, Method method, Object[] args)
                  throws  Throwable {
           System.  out .println(  "before calling:" +method);
           Object obj =  method.invoke(  sub , args);
           System.  out .println(  "after calling:" +method);
           
            return obj ;
     }
}

真实角色
package  com.nan.proxi;
public  class  RealSubject  implements  Subject {
      @Override
      public  void  request() {
           System.  out .println(  "我被代理了!"  );
     }
}

操作类
package  com.nan.proxi;
import  java.lang.reflect.InvocationHandler;
import  java.lang.reflect.Proxy;

public  class  TestMain {
      public  static  void  main(String[] args) {
           RealSubject rs =  new  RealSubject();
           InvocationHandler handler =  new  ProSubject(rs);
           Class<?> classType = handler.getClass();

           Subject subject = (Subject) Proxy. newProxyInstance(
                     classType.getClassLoader(), rs.getClass().getInterfaces(),  handler);   //生成代理

           subject.request();
     }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值