A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

interface Advice {
void beforeMethod(Method method);
void afterMethod(Method method);
}

class MyAdvice implements Advice {
long beginTime=0;
public void afterMethod(Method method) {
  long endTime=System.currentTimeMillis();
  System.out.println(method.getName()+":"+"run"+":"+(endTime-beginTime));
}
public void beforeMethod(Method method) {
  long beginTime=System.currentTimeMillis();
}
}
//代理调试类主函数中有
final ArrayList target=new ArrayList ();
  Collection proxy4 = (Collection)getProxy(target,new MyAdvice());
  proxy4.add("x");
  proxy4.add("y");
  proxy4.add("z");
  System.out.println(proxy4.size());
  System.out.println(proxy4.getClass().getName());
//为什么调用目标方法?而代理类也有值
System.out.println(proxy4);//[x, y, z]
//代理测试类的一个方法次,此方法获得目标类的代理的方法
private static Object getProxy(final Object target,final Advice advice) {
  Object proxy4=(Object)Proxy.newProxyInstance(
    target.getClass().getClassLoader(),
    target.getClass().getInterfaces(),
    new InvocationHandler(){
     public Object invoke(Object proxy, Method method, Object[] args)
       throws Throwable {
      advice.beforeMethod(method);
      Object retVal=method.invoke(target, args);
      advice.afterMethod(method);
      return retVal;
      
     }
    });
  return proxy4;
}
}

//为什么调用目标方法?而代理类也有值
System.out.println(proxy4);//[x, y, z]
客服端调用代理各个方法时,把请求转发给InvocationHandler对象,分发给目标的各个方法,
add方法运行原理是
Boolean add(Object obj){
        handler.invoke(this, this.getClass().getMethod("add"), obj);
     }
但是我们查看invoke方法,发现并没有对代理类进行操作,那么打印System.out.println(proxy4)时候;
代理对象何时装了三个元素x,y,z?

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

1 个回复

倒序浏览
代理之所以叫代理,就是它能处理目标类的某些功能,并对这些功能进行额外的系统功能绑定。代理本身是不具备功能体的,它只是把一个窗口与目标类的功能体联系了起来。
如代码所示:Object retVal=method.invoke(target, args);代理类的功能体其实还是目标类本身的功能体
而从原理来看:handler.invoke(this, this.getClass().getMethod("add"), obj);其中this指向的本类对象必定是实现了目标类的接口,那么在客户端调用的时候只要是符合这个接口的目标类,都可以将功能实现代理。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马