首页 > 学院 > 开发设计 > 正文

CGLib动态代理

2019-11-14 08:45:32
字体:
来源:转载
供稿:网友
代码package com.itheima.sPRing.cglibproxy;public class PersonDaoImpl{ public void savePerson() { System.out.println("save person"); }}package com.itheima.spring.cglibproxy;public class Transaction { public void beginTransaction(){ System.out.println("begin transcation"); } public void commit() { System.out.println("commit"); }}package com.itheima.spring.cglibproxy;import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class MyInterceptor implements MethodInterceptor{ private Transaction transaction; private Object target; public MyInterceptor(Object target, Transaction transaction ) { super(); this.transaction = transaction; this.target = target; } public Object createProxy(){ //代码增强类 Enhancer enhancer = new Enhancer(); enhancer.setCallback(this);//参数为拦截器 enhancer.setSuperclass(target.getClass());//生成的代理类的父类是目标类 return enhancer.create(); } @Override public Object intercept(Object object, Method method, Object[] arg2, MethodProxy arg3) throws Throwable { this.transaction.beginTransaction(); method.invoke(target); this.transaction.commit(); return null; }}package com.itheima.spring.cglibproxy;import org.junit.Test;/** * 通过cglib产生的是代理对象,代理类是目标类的子类 * @author xx * */public class CGLibProxyTest { @Test public void testCGlib(){ Object target = new PersonDaoImpl(); Transaction transaction = new Transaction(); MyInterceptor interceptor = new MyInterceptor(target,transaction); PersonDaoImpl personDaoImpl = (PersonDaoImpl)interceptor.createProxy(); personDaoImpl.savePerson(); }}思考1、JDK动态代理与CGLib动态代理的比较?
①Java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。 而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
②JDK动态代理只能对实现了接口的类生成代理,CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 因为是继承,所以该类或方法最好不要声明成final
③JDK代理是不需要以来第三方的库,只要要JDK环境就可以,而cglib需要第三方jar包
④CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。
2、在Spring中何时用到JDK或者CGLib实现的AOP?
①如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
②如果目标对象实现了接口,可以强制使用CGLIB实现AOP
③如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
3、如何通过调试查看当前用到的是JDK还是CGLib?CGLib的标志: JDK的标志:4、如何强制用CGLib实现AOP?
①添加CGLIB库,SPRING_HOME/cglib/*.jar
②在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
5、cglib的应用?
广泛的被许多AOP的框架使用,例如spring AOP和dynaop。hibernate使用CGLIB来代理单端single-ended(多对一和一对一)关联。

上一篇:EF6+MySql code first

下一篇:ChucK初步(6)

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表