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

来源:互联网 发布:中国新歌声网络战队 编辑:程序博客网 时间:2024/06/11 05:55
​简介

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/

0 0
原创粉丝点击