当前位置:首页 > 开发 > 编程语言 > Java > 正文

java 动态代理

发表于: 2014-07-14   作者:csh081   来源:转载   浏览:
摘要: 简单的例子: 接口:ITestProxy package reflrction.proxy; public interface ITestProxy { /**  * test001  */ public void test001(); /**  * test002  */ public void te

简单的例子:

接口:ITestProxy

package reflrction.proxy;

public interface ITestProxy {
 /**
  * test001
  */
 public void test001();
 /**
  * test002
  */
 public void test002();
}

 实现类:ProxyImpl

package reflrction.proxy.staticState;

import reflrction.proxy.ITestProxy;

public class ProxyImpl implements ITestProxy {

 @Override
 public void test001() {
  System.out.println("ProxyImpl test001>>>>>>>>>>>>>>>>>>>>>>>>>>");
  
 }

 @Override
 public void test002() {
  System.out.println("ProxyImpl test002>>>>>>>>>>>>>>>>>>>>>>>>>>");
  
 }

}

动态代理类:DynamicProxy

package reflrction.proxy.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxy implements InvocationHandler {

 private Object target;

 /**
  * 绑定委托对象并返回一个代理类
  *
  * @param target
  * @return
  */
 public Object bind(Object target) {
  this.target = target;
  // 取得代理对象

  // 要绑定接口(这是一个缺陷,cglib弥补了这一缺陷),此处this 是指$Proxy0(InvocationHandler) }
  return Proxy.newProxyInstance(target.getClass().getClassLoader(),
    target.getClass().getInterfaces(), this);

 @Override
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  Object result = null;
  System.out.println("动态代理 invoke 开始");
  // 执行方法
  result = method.invoke(target, args);
  System.out.println("动态代理 invoke 结束");
  return result;

 }

}

主函数:DynamicProxyMain

package reflrction.proxy.dynamic;

import reflrction.proxy.ITestProxy;
import reflrction.proxy.staticState.ProxyImpl;

public class DynamicProxyMain {

 /**
  * @param args
  * @throws IllegalAccessException
  * @throws InstantiationException
  */
 public static void main(String[] args) throws InstantiationException, IllegalAccessException {
  
  DynamicProxy dynamicProxy = new DynamicProxy();
  ITestProxy testProxy = (ITestProxy)dynamicProxy.bind(ProxyImpl.class.newInstance());
  testProxy.test001();
  testProxy.test002();
  System.out.println(testProxy.getClass().getName());
 }

}

运行结果:

动态代理 invoke 开始
ProxyImpl test001>>>>>>>>>>>>>>>>>>>>>>>>>>
动态代理 invoke 结束
动态代理 invoke 开始
ProxyImpl test002>>>>>>>>>>>>>>>>>>>>>>>>>>
动态代理 invoke 结束
com.sun.proxy.$Proxy0

以上代码解析:

Proxy.newProxyInstance方法会做如下几件事:

1,根据传入的第二个参数interfaces动态生成一个类,实现interfaces中的接口,该例中即ITestProxy 接口的test001  和 test002 方法。并且继承了Proxy类,重写了hashcode,toString,equals等三个方法。具体实现可参看 ProxyGenerator.generateProxyClass(...); 该例中生成了com.sun.proxy.$Proxy0

2,通过传入的第一个参数classloder将刚生成的类加载到jvm中。即将$Proxy0类load

3,利用第三个参数,调用$Proxy0的$Proxy0(InvocationHandler)构造函数 创建$Proxy0的对象,并且用interfaces参数遍历其所有接口的方法,并生成Method对象初始化对象的几个Method成员变量

4,将$Proxy0的实例返回给客户端。

现在好了。我们再看客户端怎么调就清楚了。

1,客户端拿到的是$Proxy0的实例对象,由于$Proxy0继承了ITestProxy ,因此转化为ITestProxy 没任何问题。

BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);

 

2,testProxy.test001();
       testProxy.test002();


实际上调用的是$Proxy0.test001(); $Proxy0.test002();那么$Proxy0.test001(); $Proxy0.test002()的实现就是通过InvocationHandler去调用invoke方法啦!

 

 

 

java 动态代理

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号