java技术——动态代理(cglib)

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

下面是使用cglib实现动态代理的一个例子。需要导入两个jar文件。asm.jar – Cglib的底层实现。【cglib包的底层是使用字节码处理框架ASM来转换字节码并生成新的类,所以cglib包要依赖于asm包】。 cglib.jar - Cglib的核心jar包。

被代理的类

Source code    
package com.bobohe.cglibproxy;
 
/**
 * 被代理的类
 * @author Administrator
 *
 */
public class CglibProxyTest {
	public void test(){
		System.out.println("do cglib proxy test!");
	}
}

cglib动态代理类

Source code    
package com.bobohe.cglibproxy;
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 [email protected]
 *
 */
public class CglibDynamicProxy implements MethodInterceptor {
 
	private Object target;
 
	/**
	 * 创建代理对象
	 * @param target 被代理的对象
	 * @return
	 */
	public Object getProxyInstance(Object target){
		this.target = target;
		// 声明增强类实例
		Enhancer enhancer = new Enhancer(); 
		// 设置被代理类字节码,CGLIB根据字节码生成被代理类的子类
                enhancer.setSuperclass(this.target.getClass());  
                // 设置要代理的拦截器,回调函数,即一个方法拦截   new MethodInterceptor()
                enhancer.setCallback(this); 
                // 创建代理对象 实例 
                return enhancer.create();  
	}
 
	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		// 在代理真实对象操作前 我们可以添加一些自己的操作
		System.out.println("前置代理,增强处理");
 
		proxy.invokeSuper(obj, args);
 
		// 在代理真实对象操作后 我们也可以添加一些自己的操作
		System.out.println("后置代理,增强处理");
		return null;
	}
 
}

客户端类

Source code    
package com.bobohe.cglibproxy;
public class CglibClient {  
 
    public static void main(String[] args) {  
        CglibDynamicProxy cglib = new CglibDynamicProxy();  
        CglibProxyTest proxyInstance = (CglibProxyTest) cglib.getProxyInstance(new CglibProxyTest());  
        proxyInstance.test();
    }  
 
}

总结:CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理

你可能感兴趣的:(java技术——动态代理(cglib))