动态代理模式1--基本使用

​简单介绍

Java动态代理机制的出现,使得Java程序猿不须要手工编写代理类。仅仅须要指定相应的接口及托付类对象,便能动态的获代替理类。

代理类负责将全部方法的调用托付到实际对象反射运行。在托付中。代理类能够增加自己定义功能的实现。

静态代理

1,简单介绍

普通静态代理模式,目的就是其它对象为了控制某对象的訪问,而提供代理对象间接实现。

 2,代理模式UML


3,角色介绍

    ISubject:主题角色,定义对象的详细行为。


    RealSubject:真实对象,被代理对象。实现主题角色,定义出详细行为。

    Proxy:代理对象,一般实现主题角色,并持有真实对象的引用。在内部操作真实对象。

4,详细实现

    静态代理的实现较为简单。详细可參考我之前的博客:http://blog.csdn.net/mergades/article/details/42173893

JDK动态代理相关类

    1。Java.lang.reflect.Proxy:该类主要提供静态方法用来创建代理对象。

  1. * {@code Proxy} provides static methods for creating dynamic proxy
  2. * classes and instances, and it is also the superclass of all
  3. * dynamic proxy classes created by those methods.

    getInvocationHandler方法:用于指定代理对象关联的调用处理器InvocationHandler。

  1. public static InvocationHandler getInvocationHandler(Object proxy)
  2.        throws IllegalArgumentException

newProxyInstance:获取相应指定类载入器。以及接口的动态代理类对象。

  1. @CallerSensitive
  2.    public static Object newProxyInstance(ClassLoader loader,
  3.                                          Class<?>[] interfaces,
  4.                                          InvocationHandler h)
  5.        throws IllegalArgumentException

针对Proxy类,我们能够在它的Java doc文档中看到相应的描写叙述:

    -1,代理类终于都关联一个InvocationHandler接口。该接口用来处理针对代理类的全部方法调用。

    -2,代理类必须是public。final并且不能为Abstract。由于是final的,所以不能再被继承。


    -3。代理类必须是“$ProxyN” 的命名格式。由于代理类类部实现了缓存机制,所以并非每次生成代理类对象都会是新的对象。

针对同一组接口的连续调用。会从缓存获代替理对象。


    -4,假设代理类实现了非公共接口。那么该接口必须与代理类出于同样的包中。

接口数量不能超过65535。

    


2,java.lang.reflect.InvocationHandler:指定相应动态代理类的处理器。

每次生成代理对象都必须指定该对象,能够參考proxy的newProxyInstance方法參数。


invoke方法:该方法负责集中处理针对动态代理类全部方法的调用。

  1. public Object invoke(Object proxy, Method method, Object[] args)
  2.        throws Throwable;


简单动态代理的实现

    主题接口:

  1. package com.jing.proxy;
  2. /**
  3. * 主题接口
  4. *
  5. * @author jinglongjun
  6. *
  7. */
  8. public interface ISubject {
  9. void doSomething();
  10. }

    真实对象:

  1. package com.jing.proxy;
  2. /**
  3. * 详细的被代理对象。

  4. *
  5. * @author jinglongjun
  6. *
  7. */
  8. public class HelloSubject implements ISubject {
  9. @Override
  10. public void doSomething() {
  11. System.out.println("HelloSubject: say hello to everyone!");
  12. }
  13. }

Handler对象:

  1. package com.jing.proxy;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. /**
  5. * Handler对象
  6. *
  7. * @author jinglongjun
  8. *
  9. */
  10. public class SubHandler implements InvocationHandler {
  11. private Object obj;// 持有真实对象
  12. public SubHandler(Object obj) {
  13. this.obj = obj;
  14. }
  15. @Override
  16. public Object invoke(Object proxy, Method method, Object[] args)
  17. throws Throwable {
  18. Object result = method.invoke(obj, args);// 真实对象来运行详细的方法
  19. System.out.println("说完你好。说再见》》》bye-bye!");//增加自己操作
  20. return result;
  21. }
  22. }

详细使用:

  1. package com.jing.proxy;
  2. import java.lang.reflect.Proxy;
  3. public class Test {
  4. public static void main(String[] args) {
  5. HelloSubject helloSubject = new HelloSubject();
  6. ISubject sub = (ISubject) Proxy.newProxyInstance(helloSubject.getClass()
  7. .getClassLoader(), helloSubject.getClass().getInterfaces(),
  8. new SubHandler(helloSubject));
  9. sub.doSomething();
  10. }
  11. }

运行结果:

  1. HelloSubject: say hello to everyone!
  2. 说完你好,说再见》》》bye-bye!

个人认为,代码的重点还是在生成代理对象的时候,是怎样将真实对象,和相应代理对象的InvocationHandler相互组装,实现我们终于须要的结果。详细就须要分析JDK的源代码来看了。

详细源代码,我们稍后分析。

本文主要參考:http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/

posted @ 2017-07-23 09:06  wzzkaifa  阅读(278)  评论(0编辑  收藏  举报