欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

动态代理模式——JDK动态代理

程序员文章站 2022-04-21 17:28:21
今天,我就来讲一下动态代理的设计模式。 动态代理的意义在于生成一个代理对象,来代理真实对象,从而控制真实对象的访问。操作动态代理需要两个步骤:一、代理对象和真实对象建立代理关系。二、实现代理对象的代理逻辑方法。 在Java中,有很多的动态代理技术。如:JDK、CGLIB、Javassist、ASM, ......

  今天,我就来讲一下动态代理的设计模式。

  动态代理的意义在于生成一个代理对象,来代理真实对象,从而控制真实对象的访问。操作动态代理需要两个步骤:一、代理对象和真实对象建立代理关系。二、实现代理对象的代理逻辑方法。

  在java中,有很多的动态代理技术。如:jdk、cglib、javassist、asm,其中最常用的动态代理技术有两种:一种是jdk动态代理,这是jdk自带的功能;另一种就是cglib,这是第三方提供的一种技术。

  这次主要讲的是jdk动态代理和cglib动态代理。在jdk动态代理中,我们必须使用接口,而cglib就不需要。

 

jdk 动态代理

  jdk 动态代理是 java.lang.reflect.* 包提供的方式,它必须借助一个接口才能产生代理对象,所以我们先定义一个接口。代码如下:

1 public interface helloworld {
2 
3     public void sayhelloworld();
4 }

  然后提供实现类来实现此接口。代码如下:

public class helloworldimpl implements helloworld {

    @override
    public void sayhelloworld() {
        system.out.println("hello world! 动态代理学习篇");
    }

}

  这是最简单的 java 接口与实现类的关系。这时我们开始今天学习的内容,jdk动态代理。我们先要建立代理对象和真实服务对象的关系,然后实现代理逻辑。

  在 jdk 动态代理中,要实现代理逻辑类必须去实现 java.lang.reflect.invocationhandler 接口,它里面定义了一个 invoke 方法,并且提供接口数组用于下挂代理对象。代码如下:

public class jdkproxy implements invocationhandler {
    
    //真实对象
    private object target = null;
    
    /**
     * 建立代理对象和真实对象的代理关系,并返回代理对象
     * @param obj 真实对象
     * @return           代理对象
     */
    public object bind(object target){
        this.target = target;
        return proxy.newproxyinstance(target.getclass().getclassloader(), target.getclass().getinterfaces(), this);
    }

    /**
     * 代理方法逻辑
     * @param proxy    代理对象
     * @param method 当前调度方法
     * @param args 当前方法的参数
     * @return 代理结果返回
     * @throws 异常
     */
    @override
    public object invoke(object proxy, method method, object[] args) throws throwable {
        system.out.println("进入代理逻辑方法");
        system.out.println("在调度真实对象之前的服务");
        //相当于调用 sayhelloworld 的方法
        object obj = method.invoke(target, args);
        system.out.println("在调度真实对象之后的服务");
        return obj;
    }

}

  第1步,建立代理对象和真实对象的关系。这里使用 bind 方法去完成,方法里面首先用类的属性 target 保存了真实对象,然后通过如下代码建立并生成代理对象。

proxy.newproxyinstance(target.getclass().getclassloader(), target.getclass().getinterfaces(), this);

  其中 newproxyinstance 方法包含三个参数。

  第一个参数为:类加载器。

  第二个参数为:把生成的动态代理对象下挂在哪些接口下。

  第三个参数为:定义实现方法逻辑的代理类,this 表示当前对象,它必须实现 invocationhandler 接口方法的 invoke 方法,它就是代理逻辑方法的现实方法。

  第2步,实现代理逻辑方法。 invoke 方法可以实现代理逻辑, invoke 方法的三个参数的意义如下:

  proxy:代理对象,就是 bind 方法生成的对象。

  method:当前调度的方法。

  args: 调度方法的参数。

 

测试一下jdk动态代理方法。代码如下:

public class testproxy {
    
    public static void main(string[] args) {
        jdkproxy jdktest = new jdkproxy();
        helloworld proxy = (helloworld)jdktest.bind(new helloworldimpl());
        proxy.sayhelloworld();
        
    }

}

测试结果如下:

动态代理模式——JDK动态代理

 

  这就是 jdk 动态代理,它是一种常用的动态代理。