这样和妻子解释:Java动态代理机制详解(JDK和CGLIB( 八 )
仔细观察可以看出生成的动态代理类有以下特点:
1.继承自 java.lang.reflect.Proxy , 实现了 Rechargable,Vehicle 这两个ElectricCar实现的接口;
2.类中的所有方法都是final 的;
3.所有的方法功能的实现都统一调用了InvocationHandler的invoke()方法 。
文章插图
cglib 生成动态代理类的机制----通过类继承:
JDK中提供的生成动态代理类的机制有个鲜明的特点是: 某个类必须有实现的接口 , 而生成的代理类也只能代理某个类接口定义的方法 , 比如:如果上面例子的ElectricCar实现了继承自两个接口的方法外 , 另外实现了方法bee() ,则在产生的动态代理类中不会有这个方法了!更极端的情况是:如果某个类没有实现接口 , 那么这个类就不能同JDK产生动态代理了!
幸好我们有cglib 。 “CGLIB(Code Generation Library) , 是一个强大的 , 高性能 , 高质量的Code生成类库 , 它可以在运行期扩展Java类与实现Java接口 。 ”
cglib 创建某个类A的动态代理类的模式是:
1. 查找A上的所有非final的public类型的方法定义;2. 将这些方法的定义转换成字节码;3. 将组成的字节码转换成相应的代理的class对象;4. 实现MethodInterceptor接口 , 用来处理对代理类上所有方法的请求(这个接口和JDK动态代理InvocationHandler的功能和角色是一样的)
一个有趣的例子:定义一个Programmer类 , 一个Hacker类
package samples;/*** 程序猿类* @author louluan*/public class Programmer {public void code(){System.out.println("I'm a Programmer,Just Coding.....");}}
package samples;import java.lang.reflect.Method;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;/** 实现了方法拦截器接口*/public class Hacker implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {System.out.println("**** I am a hacker,Let's see what the poor programmer is doing Now...");proxy.invokeSuper(obj, args);System.out.println("****Oh,what a poor programmer.....");return null;}}
package samples;import net.sf.cglib.proxy.Enhancer;public class Test {public static void main(String[] args) {Programmer progammer = new Programmer();Hacker hacker = new Hacker();//cglib 中加强器 , 用来创建动态代理Enhancer enhancer = new Enhancer();//设置要创建动态代理的类enhancer.setSuperclass(progammer.getClass());// 设置回调 , 这里相当于是对于代理类上所有方法的调用 , 都会调用CallBack , 而Callback则需要实行intercept()方法进行拦截enhancer.setCallback(hacker);Programmer proxy =(Programmer)enhancer.create();proxy.code();}}
程序执行结果:
文章插图
让我们看看通过cglib生成的class文件内容:
【这样和妻子解释:Java动态代理机制详解(JDK和CGLIB】package samples;import java.lang.reflect.Method;import net.sf.cglib.core.ReflectUtils;import net.sf.cglib.core.Signature;import net.sf.cglib.proxy.Callback;import net.sf.cglib.proxy.Factory;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class ProgrammerEnhancerByCGLIBfa7aa2cd extends Programmerimplements Factory{//......省略private MethodInterceptor CGLIB$CALLBACK_0;// Enchaner传入的methodInterceptor// ....省略public final void code(){MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;if (tmp4_1 == null){tmp4_1;CGLIB$BIND_CALLBACKS(this);//若callback 不为空 , 则调用methodInterceptor 的intercept()方法}if (this.CGLIB$CALLBACK_0 != null)return;//如果没有设置callback回调函数 , 则默认执行父类的方法super.code();}//....后续省略}
推荐阅读
- 程序员为教师妻子开发应用:将iPhone变成文档摄像头
- 三星Z Flip3可能就长这样了!副屏尺寸和镜头是亮点
- realme国潮锦鲤手机为什么叫V15?徐起解释命名规则
- “机器人妻子”上市遭抢购,是在解决刚需,还是在挑战伦理?
- 微软浏览器2021年迎重大版本:这样的Edge 88你喜欢吗
- 女子7千买新手机,不到2天就出问题了,售后:没法解释
- 中国这项技术领先世界,首次发起挑战,英国人:美国可不敢这样玩
- 雷军回应小米11标准版取消附送充电器:5年前我就有这样的困扰
- 三星屏下镜头机型专利曝光 这样的设计方案很完美
- 欧盟17国终于“出手了”!美国不愿看到这样的结果