经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
动态代理模式——JDK动态代理
来源:cnblogs  作者:HHH燕  时间:2019/10/28 10:28:02  对本文有异议

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

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

  在Java中,有很多的动态代理技术。如:JDK、CGLIB、Javassist、ASM,其中最常用的动态代理技术有两种:一种是JDK动态代理,这是JDK自带的功能;另一种就是CGLIB,这是第三方提供的一种技术。

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

 

JDK 动态代理

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

  1. 1 public interface HelloWorld {
  2. 2
  3. 3 public void sayHelloWorld();
  4. 4 }

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

  1. public class HelloWorldImpl implements HelloWorld {
  2. @Override
  3. public void sayHelloWorld() {
  4. System.out.println("Hello World! 动态代理学习篇");
  5. }
  6. }

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

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

  1. public class JdkProxy implements InvocationHandler {
  2. //真实对象
  3. private Object target = null;
  4. /**
  5. * 建立代理对象和真实对象的代理关系,并返回代理对象
  6. * @param obj 真实对象
  7. * @return 代理对象
  8. */
  9. public Object bind(Object target){
  10. this.target = target;
  11. return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
  12. }
  13. /**
  14. * 代理方法逻辑
  15. * @param proxy 代理对象
  16. * @param method 当前调度方法
  17. * @param args 当前方法的参数
  18. * @return 代理结果返回
  19. * @throws 异常
  20. */
  21. @Override
  22. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  23. System.out.println("进入代理逻辑方法");
  24. System.out.println("在调度真实对象之前的服务");
  25. //相当于调用 sayHelloWorld 的方法
  26. Object obj = method.invoke(target, args);
  27. System.out.println("在调度真实对象之后的服务");
  28. return obj;
  29. }
  30. }

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

  1. Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);

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

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

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

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

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

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

  method:当前调度的方法。

  args: 调度方法的参数。

 

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

  1. public class TestProxy {
  2. public static void main(String[] args) {
  3. JdkProxy jdkTest = new JdkProxy();
  4. HelloWorld proxy = (HelloWorld)jdkTest.bind(new HelloWorldImpl());
  5. proxy.sayHelloWorld();
  6. }
  7. }

测试结果如下:

 

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

原文链接:http://www.cnblogs.com/HHHY/p/11746709.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号