Cglib动态代理

       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方法,无法进行代理


posted on 2015-04-13 20:21  吴一达  阅读(139)  评论(0编辑  收藏  举报

导航