AOP编程之JDK动态代理和Cglib动态代理
2013-08-17 01:31
453 查看
最近开发过程中遇到一些问题,为了可以好好的解决,研究了几天的动态代理。记下来,怕以后忘记了。
动态代理适用的情景:
某个类的某个方法已经做好了,你在不想或者不能改动源代码的情况下,要做一些额外的操作,这时候就可以使用代理设计模式。
例如,周杰伦要举行新唱片的的签名发布会,他总不能自己去布置会场吧。所以他就请了他的经理人Kim去帮忙布置场地罗,这个Kim就是属于代理的角色了。他要在Joy签名会之前去布置场地,签名会之后清理场地。
下面我们来看看JDK代理怎么做的。
1.首先Joy同学需要先声明自己有一个签名会,也就是interface。然后再去开这个签名会。
2.然后我们的JDK代理就出场了
3.双方都准备就绪了,我们现在开始签合同工作了。
可以看到最后的结果是:
jdk say:签名会开始之前,我要帮忙布置场地...
joy say:大家好,我是Joy,今天我在这里举行签名会哦...
jdk say:签名会结束了,我要清理场地。
大家可以发现,Joy开演唱会之前还有做一次声明,多么让人不爽快的interface啊。所以SHE开签名会的时候就换了一个叫cglib的代理。
下面来看cglib代理是怎么做的。
1.首先,SHE的演唱会还是要自己去开的。
2.然后我们的Cglib其实是一家公司来的员工了,他可以为好多的明星布置会场的。成立这个比较好使代理公司,总的多投入点成本吧。
引入asm-3-3-1.jar和cglib-2.2.jar
3.接下来就是签约工作了
4.最后你会发现,演唱会灰常的成功啦。
cglib say:我在布置演唱会的场地.....
she say:大家好,我们是SHE,下面为大家带来《星光》....
cglib say:演唱会结束了,我在清理场地.....
对比JDK代理和Cglib代理可以发现,JDK多了一个接口。
为什么JDK代理只能针对接口呢?
JDK动态代理的原理是根据定义好的规则,用传入的接口创建一个新类,这就是为什么采用动态代理时为什么只能用接口引用指向代理,而不能用传入的类引用执行动态类,有兴趣的自己去查源代码哈。
而Cglib则采用ASM工具,直接修改字节码。所以不用接口规范。
动态代理适用的情景:
某个类的某个方法已经做好了,你在不想或者不能改动源代码的情况下,要做一些额外的操作,这时候就可以使用代理设计模式。
例如,周杰伦要举行新唱片的的签名发布会,他总不能自己去布置会场吧。所以他就请了他的经理人Kim去帮忙布置场地罗,这个Kim就是属于代理的角色了。他要在Joy签名会之前去布置场地,签名会之后清理场地。
下面我们来看看JDK代理怎么做的。
1.首先Joy同学需要先声明自己有一个签名会,也就是interface。然后再去开这个签名会。
public interface Joy { public void holdSignature(); }
public class JoyImpl implements Joy{ public void holdSignature() { System.out.println("joy say:大家好,我是Joy,今天我在这里举行签名会哦..."); } }
2.然后我们的JDK代理就出场了
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //这是专门帮人家布置场地的JDK代理 public class JDKProxy implements InvocationHandler{ //要代理的对象,也即是帮哪个明星做场地啦,今天可能是Joy,明天可能就是SHE了 private Object star; public JDKProxy(Object star) { this.star = star; } public Object getProxySatr(){ return Proxy.newProxyInstance( star.getClass().getClassLoader(), star.getClass().getInterfaces(), this); } public Object invoke(Object obj, Method method, Object[] params) throws Throwable { System.out.println("jdk say:签名会开始之前,我要帮忙布置场地..."); //明星开始他的签名会了 Object result = method.invoke(star, params); System.out.println("jdk say:签名会结束了,我要清理场地。"); return result; } }
3.双方都准备就绪了,我们现在开始签合同工作了。
public static void main(String[] args) { //jdkProxy代理接到order是帮joy布置场地呢。 JDKProxy jdkProxy = new JDKProxy(new JoyImpl()); //请出代理的明星,让他签名去咯 Joy joy = (Joy) jdkProxy.getProxySatr(); joy.holdSignature(); }
可以看到最后的结果是:
jdk say:签名会开始之前,我要帮忙布置场地...
joy say:大家好,我是Joy,今天我在这里举行签名会哦...
jdk say:签名会结束了,我要清理场地。
大家可以发现,Joy开演唱会之前还有做一次声明,多么让人不爽快的interface啊。所以SHE开签名会的时候就换了一个叫cglib的代理。
下面来看cglib代理是怎么做的。
1.首先,SHE的演唱会还是要自己去开的。
public class SHE { public void musicShow() { System.out.println("she say:大家好,我们是SHE,下面为大家带来《星光》...."); } }
2.然后我们的Cglib其实是一家公司来的员工了,他可以为好多的明星布置会场的。成立这个比较好使代理公司,总的多投入点成本吧。
引入asm-3-3-1.jar和cglib-2.2.jar
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor{ public Enhancer enhancer = new Enhancer(); public<T> Object getCglibProxy(Class<T> star){ //指定这次要伺候的明星 enhancer.setSuperclass(star); //要做什么呢?就是下面的intercept里面干的事 enhancer.setCallback(this); //合约签订,把你的暂时仆人送过去服务你了。 return enhancer.create(); } public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("cglib say:我在布置演唱会的场地....."); //boss可以开演唱会了 Object result = proxy.invokeSuper(obj, args); System.out.println("cglib say:演唱会结束了,我在清理场地....."); return result; } }
3.接下来就是签约工作了
public static void main(String[] args) { CglibProxy cglibProxy = new CglibProxy(); SHE she = (SHE) cglibProxy.getCglibProxy(SHE.class); she.musicShow(); }
4.最后你会发现,演唱会灰常的成功啦。
cglib say:我在布置演唱会的场地.....
she say:大家好,我们是SHE,下面为大家带来《星光》....
cglib say:演唱会结束了,我在清理场地.....
对比JDK代理和Cglib代理可以发现,JDK多了一个接口。
为什么JDK代理只能针对接口呢?
JDK动态代理的原理是根据定义好的规则,用传入的接口创建一个新类,这就是为什么采用动态代理时为什么只能用接口引用指向代理,而不能用传入的类引用执行动态类,有兴趣的自己去查源代码哈。
而Cglib则采用ASM工具,直接修改字节码。所以不用接口规范。
相关文章推荐
- Java动态代理之JDK动态代理和CGLib动态代理 面向切面编程AOP原理
- spring aop学习8:spring对jdk和cglib动态代理的选择
- spring对AOP的支持(JDK的动态代理实现AOP和CGLIB实现AOP)
- AOP学习心得&jdk动态代理与cglib比较
- Spring中AOP实现的两种方式之JDK和cglib的动态代理
- 通过CGLIB实现AOP的浅析(顺便简单对比了一下JDK的动态代理)
- spring框架学习(八)—静态代理、JDK与CGLIB动态代理、AOP+IoC
- Sping-AOP:cglib动态代理与JDK动态代理的区别
- Spring系列之 (十一):AOP实现方式:动态代理的两个方式(JDK和Cglib)
- 做一个合格的程序猿之浅析Spring AOP源码(十三) jdk的动态代理和cglib的代理
- Java动态代理模式jdk和cglib的2种实现以及二者的区别(AOP面向切面的前奏)
- Spring aop 基于JDK动态代理和CGLIB代理的原理以及为什么JDK代理需要基于接口
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
- 浅析Spring AOP源码(十三) jdk的动态代理和cglib的代理
- Spring中AOP实现的两种方式之JDK和cglib的动态代理
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
- AOP的底层实现-CGLIB动态代理和JDK动态代理
- Spring学习总结——静态代理、JDK与CGLIB动态代理、AOP+IoC
- 通过CGLIB实现AOP的浅析(顺便简单对比了一下JDK的动态代理)
- jdk和cglib动态代理(aop)