黑马程序员技术交流社区

标题: JDK 中InvocationHandler和Proxy产生代理的问题 [打印本页]

作者: 张源锋    时间: 2013-3-31 21:59
标题: JDK 中InvocationHandler和Proxy产生代理的问题
本帖最后由 张源锋 于 2013-4-6 22:51 编辑

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class InvoceHandler implements InvocationHandler{
Object target ;

public InvoceHandler(Object target){
  this.target=target;
}

public void begin(){
  System.out.println("save start");
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  this.begin();
  method.invoke(target, args);
  return null;
}
}

import java.lang.reflect.Proxy;

public class Test {
    public static void main(String[] args) {
          InvoceHandler in =new InvoceHandler(new UserDao());
          UserDaoInterface u =(UserDaoInterface)Proxy.newProxyInstance(UserDao.class.getClassLoader(),
           UserDao.class.getInterfaces(),in);
           u.save();
    }
}

谁能告诉我产生这个 代理的过程,我现在一个头两个大。希望大神们能用通俗点语言解释一下,小弟谢过了


作者: Lobster    时间: 2013-4-6 22:26
{:soso_e199:}这么久没人跟你解释我来简单解释一下吧。。。。

{:soso_e199:}首先要用代理类首先要创建一个动态代理类实例,也就是Proxy,由于Proxy的构造方法不是public的于是要实例化这个类需要反射它的构造方法。另外就是可以使用Proxy的一个静态方法来实例化。

{:soso_e199:}接下来Proxy实例化需要一个InvocationHandler接口的实现类,这个类相当于是这个代理的实际处理类,用来实际的处理代理类调用的方法。在这个类中的invoke方法就相当于实际执行的方法。

{:soso_e199:}这个方法中的参数第一个是这个代理类对象,第二个是这个代理类在执行的方法,第三个是该方法的参数,通过调用这个方法能够完成被代理方法的基本功能,并且能够在该被代理方法的前后添加额外的代码,也就是相当于在这个方法的切面上写代码了。
作者: 刘焕新    时间: 2013-4-6 23:44
本帖最后由 刘焕新 于 2013-4-6 23:55 编辑
  1. import java.lang.reflect.InvocationHandler;
  2. import java.lang.reflect.Method;
  3. import java.lang.reflect.Proxy;


  4. class InvoceHandler implements InvocationHandler {
  5.         // 原始对象,即:将要被代理的对象:
  6.         Object target;

  7.         // 代理者自身构造函数:
  8.         public InvoceHandler(Object target) {
  9.                 this.target = target;
  10.         }

  11.         public void begin() {
  12.                 System.out.println("save start");
  13.         }

  14.         // 实现InvocationHandler接口的invoke方法:
  15.         public Object invoke(Object proxy, // 此类代理对象本身,可打印proxy.getClass()查看Class信息
  16.                         Method method, // Method对象包含目标方法的信息
  17.                         Object[] args) // 目标方法的执行参数
  18.                         throws Throwable {
  19.                
  20.                 this.begin(); // 这是目标方法执行前的操作:

  21.                 // 通过Method对象,反射调用原始对象的目标方法,并传入执行参数
  22.                 Object obj = method.invoke(target, args);

  23.                 //目标方法执行后---此处还可以插入别的操作:

  24.                 //返回目标方法执行后的返回值
  25.                 return obj;
  26.         }
  27. }

  28. public class InvocationTest {
  29.         public static void main(String[] args) {
  30.                 //这个就是原始对象,代理对象将可以代替它做些事情:
  31.                 UserDao userDao = new UserDao();
  32.                
  33.                 //将一个原对象传入InvocationHandler接口的实现类的对象中:
  34.                 InvoceHandler in = new InvoceHandler(userDao);
  35.                
  36.                 ClassLoader loader = UserDao.class.getClassLoader();
  37.                 Class[] interfaces = UserDao.class.getInterfaces();
  38.                
  39.                 //最疑惑的应该是这个方法吧,这是用Proxy类的静态方法创建对象,它的实例对象是通过指定原对象及其实现的接口类,和InvocationHandler的实现类,
  40.                 //在程序运行时,动态创建代理类对象。本人学的深度有限,暂时也只会简单的分析和理解,内部是通过反射实现的,要想看实现过程,可以看源码。
  41.                 Object obj = Proxy.newProxyInstance(loader, interfaces, in);
  42.                
  43.                 //此代理对象内具备原对象的接口的所有方法,也就是说,原对象实现的接口里有什么方法,代理对象就可以调用什么方法:
  44.                 UserDaoInterface u = (UserDaoInterface) obj;
  45.                
  46.                 //使用代理对象来执行原始对象的方法时,代理对象不仅会执行原始对象的方法,
  47.                 //还会执行invoke()方法中定义的其他操作,也就是invoke()方法里,除了method.invke()的其他操作:
  48.                 u.save(); //save()就是目标方法!
  49.         }
  50. }

  51. //定义接口,是为了实现面向接口编程
  52. interface UserDaoInterface {
  53.         void save();
  54. }

  55. //定义上面接口的实现类:
  56. class UserDao implements UserDaoInterface {
  57.         @Override
  58.         public void save() {
  59.         }
  60. }
复制代码





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2