下面我们再来看下cglib的实现,首先看下测试类吧,上面已经看到了,主要是实现了MethodInterceptor方法,里面一个主要的类是Enhancer,那我们来看下cglib是怎么生成代理类的。
Cglib主要是这个方法
enhancer.setSuperclass(clz);//设置父类,从这个地方也可以看到cglib是通过子类化来实现代理的
enhancer.setCallback(this); //设置回调函数为this,其实只要实现了MethodInterceptor,都可以作为回调函数,不一定要是当前类
enhancer.create(); //创建代理类
设置没有什么好说的,下面我们具体看下create方法,再来一幅简图
同样的,从这幅图上,生成字节码仍然比较重要,像上面一样,举个例子,看怎么生成的,cglib使用asm作为生成字节码的基础类库,比较麻烦和啰嗦,见重点的写一些
//1、开始写方法体内容,首先是判断是否为空
e = context.beginMethod(ce, method); Label nullInterceptor = e.make_label(); context.emitCallback(e, context.getIndex(method)); e.dup(); e.ifnull(nullInterceptor);
//2、得到相应方法的method,这个method是指被代理类的method,在代理类中是一个属性
e.load_this(); e.getfield(methodField); if (method.getSignature().getArgumentTypes().length == 0) { e.getfield(EMPTY_ARGS_NAME); } else { e.create_arg_array(); }
//3、得到相应方法代理类的method,在代理类中是一个属性
e.getfield(methodProxyField);
//4、调用interceptor的方法进行代理,此时的METHOD_INTERCEPTOR =TypeUtils.parseType("net.sf.cglib.proxy.MethodInterceptor"),INTERCEPT = new Signature()
e.invoke_interface(METHOD_INTERCEPTOR, INTERCEPT);
上面太枯燥,直接看jd反编译的东东
上面的CGLIB$CALLBACK_0,就是我们要传入的MethodInterceptor接口,两个参数就是学问了
GLIB$sayHello$0$Proxy = MethodProxy.create(tmp27_17, (498ec6d0.CGLIB$sayHello$0$Method = Class.forName("com.HelloWorld").getDeclaredMethod("sayHello", new Class[] { Class.forName("java.lang.String") })).getDeclaringClass(), localClass, "(Ljava/lang/String;)Ljava/lang/String;", "sayHello", "CGLIB$sayHello$0");
比较长,总的意思就是CGLIB$sayHello$0$Method 这个就是被代理类的方法也就是sayhello方法,CGLIB$sayHello$0$Proxy就是代理类的方法,这个方法用asm完全重写,没有用反射。
上面生成完之后,最后将那个MethodInterceptor的实现设置进去,就实例化为了一个代理对象
从上面可以看到,代理类的实现很简单,就是讲所有的方法,用你的实现方法全部替换下,所以如果比较细心和勇于尝试的话,自己都可以实现代理框架,
一些因为代理产生的问题,如果能明白里面参数的构成和原理,就会一目了然
比如在java的实现中,你要看下第一个参数是什么类型的,真的是Proxy的子类么?
publicclass DynaHello implements InvocationHandler {
private Object obj;
public DynaHello(Object obj) { this.obj = obj;}
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println(proxy);
long start = System.currentTimeMillis();
Object o = method.invoke(obj, args);
System.out.println("Call to sayHello took "+ (System.currentTimeMillis() - start) + " ms.");
return o;
}
}
如果用上面的代码作为InvocationHandler的实现,在执行的时候就会报错,大家就会知道为什么了。
原因是:在代理类也就是proxy中,所有的方法都委托给了InvocationHandler的invoke方法进行处理,而toString方法也不例外,因此就会出现循环调用这种情况
Proxy的toString方法内联下就是如下的形式
public String toString() {
System.out.println(proxy.toString());//明显的循环调用了,所以跑错
long start = System.currentTimeMillis();
Object o = method.invoke(obj, args);
System.out.println("Call to sayHello took "+ (System.currentTimeMillis() - start) + " ms.");
return o;
}
其他的就不说了,自己体会,肯定会有人想突破java动态代理,必须实现接口的限制 这篇文章满足你的求知欲https://www.ibm.com/developerworks/cn/java/j-lo-proxy2/
另外fastjson为什么说自己的序列化会很快,并且序列化的结果比较小,就是因为用了asm,针对每一个pojo写出特定化的序列化类,这样就会比那种通用的序列化类快一些,所以说asm是个好东西。
上面字节码生成的东东,可以自己玩下,还是很有意思的。。。。。。
搞了这么多,你肯定看累了,我也写累了,睡了。
相关推荐
本文通过分析Java动态代理的机制和特点,解读动态代理类的源代码,并且模拟推演了动态代理类的可能实现,向读者阐述了一个完整的 Java动态代理运作过程,希望能帮助读者加深对Java动态代理的理解和应用。本文的标签...
Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。
关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理。 代理模式是常用的java设计模式,他的特征是代理类与委托类有...
前言: 近一直在分析hadoop的RPC机制。...下面是动态代理的简单的代码实现,我们一起来看看吧。 代码如下: package cn.xiaolu; import java.lang.reflect.InvocationHandler; import java.lang.refle
分析了当今几种路由算法的不足和研究了移动代理优越性的基础上,提出了一种基于移动代理的动态路由协议算法的设计方案.该算法用移动代理去发现网络的短期状态,并用服务代理保存网络的长期运行状况.该文还用JAVA和IBM...
Microsoft代理服务系统的分析与实现 用Proxy+共享Internet联接 A:一般程序如何在内部网访问Internet (superboy) B:用socksonline+e-border通过http端口玩mud游戏 (superboy) C: 通过socksonline上mirc聊天...
文件中有附使用实例图。 用来做http协议分析的小工具,特别简单,适合我这种懒人。 推荐一把。...2. 设置浏览器的代理为 localhost:8000, 访问网站以后就可以做相关分析。 输入输出一目了然,对吧。
数据传输系统,采用简单对象访问协议( SOAP),提供定时业务组件调用,自动数据挖掘技术和远程数据传 输、接收、汇总、分析功能。实现总部对异地分支机构的及时控制和分析。它主要通过外挂业务组件来实 现业务逻辑...
哪怕没有看过源码的同学也应该知道,AOP是通过动态代理实现的,动态代理又分为两个部分:JDK动态代理和CGLIB动态代理 确实,Spring也就是通过这两种方式来实现AOP相关功能,下面就通过源码来简单求证下
JAVA 中的代理模式介绍,课本上一般讲的比较晦涩简单,这个文档讲的比较生动易懂,很有帮助。
基于webmagic + springboot + mybatis的Java爬虫,使用Echarts进行数据可视化分析,提供了从爬虫获取数据到数据持久化、数据可视化分析以及构建简单的代理池等一整套解决方案模板。 【项目资源】: 包含前端、后端、...
【店铺数据分析】服装人必备 1、畅滞销款分析 畅滞销款分析是单店货品销售数据分析中最简单、最直观,也是最重要的数据因素之一。畅滞销款式的分析首先可以提高订货的审美观和对所操作品牌风格定位的把握,多次的畅...
是一个简单的本机HTTP代理服务器软件,使用它你可以使用HTTP代理服务器上网进行浏览,下载软件....程序还具有过滤弹出式广告窗口,代理服务器的地址和速度分析,网络带宽监测,网络浏览文件的自动清除等功能,非常容易使用!
针对现有的代理环签名方案都是基于双线性对运算或指数运算且计算效率不高的问题, 提出了...通过对方案的复杂性分析, 只需要进行2n 1次的乘法运算(n表示环成员的个数), 证明系统是己知最有效的无证书代理环签名方案。
国内服装零售终端数据分析的现状 就目前国内服装零售终端的数据分析状况看,绝大部分零售商或代理商只局限在对 年、月、周、日销售额和毛利润进行简单统计,而对数据的细微变化则关注甚少,以及 如对产品自身及消费...
提出了一个新的基于双线性对的基于身份的强代理盲签名方案,并构造了一个基于身份的多级强代理盲签名方案,实现了签名权利在许可范围内逐级向下代理的要求,并对方案的安全性和执行效率进行了分析。同时,方案也满足强...
以前写的一些分析http的demo,代码没有整理了,保持原样,大家不要介意哦:) 分析http需要一个抓包工具 本人已上传一个绿色版 ...http代理访问(呵呵,其实这个不算,就是往一个代理IP端口发http包即可)
基于代理的模拟已成功应用于建模复杂的组织行为并改善或优化组织绩效的各个方面。 提出了通过遗传算法的应用来支持智能的智能体,... 该方法不仅允许进行系统级优化,而且还提供可以分析以确定构成有效代理行为的数据。