CGLIB动态代理的用法

JDK动态代理必须提供接口才能使用,在一些不能提供接口的环境中,就用CGLIB动态代理。它的优势在于不需要提供接日,只要一个非抽象类就能实现动态代理。 掌握JDK动态代理就很容易掌握CGLIB动态代理,因为它们是相似的,所以你可以先看看源码看源码深入了解JDK动态代理深这篇文章真的比较深,看完再看这篇就很OK

1.编写代理逻辑

  1. import org.springframework.cglib.proxy.Enhancer;
  2. import org.springframework.cglib.proxy.MethodInterceptor;
  3. import org.springframework.cglib.proxy.MethodProxy;
  4. import java.lang.reflect.Method;
  5. public class CglibProxytest implements MethodInterceptor {
  6. /**
  7. * 生成CGLIB代理对象
  8. * @param cls
  9. * @return
  10. */
  11. public Object getProxy(Class cls){
  12. //CGLIB enhancer增强类对象
  13. Enhancer enhancer=new Enhancer();
  14. //设置代理类
  15. enhancer.setSuperclass(cls);
  16. //定义代理逻辑对象为当前对象 ,对象要继承MethodInterceptor。并实现逻辑方法intercept
  17. enhancer.setCallback(this);
  18. return enhancer.create();
  19. }
  20. /**
  21. * 代理逻辑方法
  22. * @param proxy 代理对象
  23. * @param method 方法
  24. * @param args 方法参数
  25. * @param methodProxy 方法代理
  26. * @return
  27. * @throws Throwable
  28. */
  29. @Override
  30. public Object intercept(Object proxy, Method method, Object[] args,
  31. MethodProxy methodProxy)throws Throwable
  32. {
  33. System.out.println("调用代理对象前");
  34. Object result=methodProxy.invokeSuper(proxy,args);//真的是代理对象,不像JDk代理,还是真实对象
  35. System.out.println("调用代理对象后");
  36. return result;
  37. }

这里用了CGLIB的加强者Enhancer,通过设置超类的方法setSuperclass,然后通过setCallback方法设置哪个类为它的代理类。其中,参数为this就意味着是当前对象,那就要求用this这个对象实现接口Methodlnterceptor的方法intercept,然后返回代理对象。那么此时当前类的intercept方法就是其代理逻辑方法,其参数内容见代码注解,我们在反射真实对象方法前后进行了打印,CGLIB是通过如下代码完成的。

  1. Object result=methodProxy.invokeSuper(proxy,args);

测试代码

  1. public class Dog {
  2. public void isAnimal()
  3. {
  4. System.out.println("我是动物");
  5. }
  6. }
  7. public class test {
  8. public static void main(String arg[])
  9. { CglibProxytest cglib=new CglibProxytest();
  10. Dog a=(Dog)cglib.getProxy(Dog.class)
  11. a.isAnimal(); //调用代理对象的isAnimal()方法
  12. }
  13. }

结果:

  1. 调用代理对象前
  2. 我是动物
  3. 调用代理对象后

掌握JDK动态代理就很容易掌握CGLIB动态代理,因为它们是相似的。它们都是用getProxy方法生成代理对象,制定代理的逻辑类。而代理逻辑类要实现一个接口的个方法,那么这个接口定义的方法就是代理对象的逻辑方法,它可以控制真实对象的方法。