JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。
委托类:
package com.reflect.proxy; public class GunDog1 { public void info() { System.out.println("我是一只美丽的猎狗"); } public void run() { System.out.println("我非常的奔跑迅速"); } }
通用的方法:
package com.reflect.proxy; public class DogUtil { public void method1(){ System.out.println("=====模拟第1个通用方法======"); } public void method2(){ System.out.println("=====模拟第2个通用方法======"); } }
代理类“:
interceptor(Object obj,Method method,Object[] args ,MethodProxy proxy) 是CGLib定义的Interceptor接口的方法,它拦截所有目标类方法的调用 ,obj表示目标类的实例;method为目标类方法的反射对象;args为方法的动态入参;而proxy为代理类方法实例.
package com.reflect.proxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * 使用cglib动态代理 * @author yulei * */ public class GunDogCglib implements MethodInterceptor { private Object target; /** * 创建代理对象 */ public Object getInstance(Object target){ this.target=target; Enhancer enhancer=new Enhancer(); //设置要创建子类的类 enhancer.setSuperclass(this.target.getClass()); //回调方法 enhancer.setCallback(this); //通过字节码技术动态创建子类实例 return enhancer.create(); } @Override public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { DogUtil du=new DogUtil(); //执行DogUtil中的method1 du.method1(); Object result= methodProxy.invokeSuper(object, args); //执行DogUtil中的Method2 du.method2(); return result; } }
测试类:
package com.reflect.proxy; public class TestCglib { /** * @param args */ public static void main(String[] args) { GunDogCglib dogCglib=new GunDogCglib(); GunDog1 gunDog1=(GunDog1) dogCglib.getInstance(new GunDog1()); gunDog1.run(); } }输出:
=====模拟第1个通用方法====== 我非常的奔跑迅速 =====模拟第2个通用方法======
CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理