java 动态代理

简单的例子:

接口: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方法啦!

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值