CGLib动态代理

来源:互联网 发布:死是什么感觉 知乎 编辑:程序博客网 时间:2024/06/15 16:52
代码
  1. package com.itheima.spring.cglibproxy;
  2. public class PersonDaoImpl{
  3. public void savePerson() {
  4. System.out.println("save person");
  5. }
  6. }
  1. package com.itheima.spring.cglibproxy;
  2. public class Transaction {
  3. public void beginTransaction(){
  4. System.out.println("begin transcation");
  5. }
  6. public void commit() {
  7. System.out.println("commit");
  8. }
  9. }
  1. package com.itheima.spring.cglibproxy;
  2. import java.lang.reflect.Method;
  3. import net.sf.cglib.proxy.Enhancer;
  4. import net.sf.cglib.proxy.MethodInterceptor;
  5. import net.sf.cglib.proxy.MethodProxy;
  6. public class MyInterceptor implements MethodInterceptor{
  7. private Transaction transaction;
  8. private Object target;
  9. public MyInterceptor(Object target, Transaction transaction ) {
  10. super();
  11. this.transaction = transaction;
  12. this.target = target;
  13. }
  14. public Object createProxy(){
  15. //代码增强类
  16. Enhancer enhancer = new Enhancer();
  17. enhancer.setCallback(this);//参数为拦截器
  18. enhancer.setSuperclass(target.getClass());//生成的代理类的父类是目标类
  19. return enhancer.create();
  20. }
  21. @Override
  22. public Object intercept(Object object, Method method, Object[] arg2,
  23. MethodProxy arg3) throws Throwable {
  24. this.transaction.beginTransaction();
  25. method.invoke(target);
  26. this.transaction.commit();
  27. return null;
  28. }
  29. }
  1. package com.itheima.spring.cglibproxy;
  2. import org.junit.Test;
  3. /**
  4. * 通过cglib产生的是代理对象,代理类是目标类的子类
  5. * @author xx
  6. *
  7. */
  8. public class CGLibProxyTest {
  9. @Test
  10. public void testCGlib(){
  11. Object target = new PersonDaoImpl();
  12. Transaction transaction = new Transaction();
  13. MyInterceptor interceptor = new MyInterceptor(target,transaction);
  14. PersonDaoImpl personDaoImpl = (PersonDaoImpl)interceptor.createProxy();
  15. personDaoImpl.savePerson();
  16. }
  17. }


思考
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(多对一和一对一)关联。
0 0
原创粉丝点击