Cglib介绍

CGlib概述:
cglib(Code Generation Library )是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。
cglib封装了asm,可以在运行期动态生成新的class。
cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。

 

一个好的例子:

http://www.blogjava.net/stone2083/archive/2008/03/16/186615.html

 

一、JDK的动态代理类

Java代码
  1. public   interface  IService {  
  2.     boolean  getService(String data);  
  3. }  
public interface IService {
	boolean getService(String data);
}

 

Java代码
  1. public   class  ServiceImpl  implements  IService {  
  2.   
  3.     public   boolean  getService(String data) {  
  4.         if  ( "A" .equals(data)) {  
  5.             return   true ;  
  6.         } else  {  
  7.             return   false ;  
  8.         }  
  9.     }  
  10.   
  11. }  
public class ServiceImpl implements IService {

	public boolean getService(String data) {
		if ("A".equals(data)) {
			return true;
		} else {
			return false;
		}
	}

}

 

Java代码
  1. import  java.lang.reflect.InvocationHandler;  
  2. import  java.lang.reflect.Method;  
  3.   
  4. public   class  ServiceHandler  implements  InvocationHandler {  
  5.     private  Object delegateObj;  
  6.   
  7.     public  ServiceHandler(Object delegateObj) {  
  8.         this .delegateObj = delegateObj;  
  9.     }  
  10.   
  11.     public  Object invoke(Object proxy, Method method, Object[] args)  
  12.             throws  Throwable {  
  13.         System.out.println("Begin Transaction...." );  
  14.         boolean  rtn = (Boolean) method.invoke(delegateObj, args);  
  15.         System.out.println("End Transaction...." );  
  16.         return  rtn;  
  17.     }  
  18.   
  19. }  
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ServiceHandler implements InvocationHandler {
	private Object delegateObj;

	public ServiceHandler(Object delegateObj) {
		this.delegateObj = delegateObj;
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("Begin Transaction....");
		boolean rtn = (Boolean) method.invoke(delegateObj, args);
		System.out.println("End Transaction....");
		return rtn;
	}

}

 

Java代码
  1. import  java.lang.reflect.Proxy;  
  2.   
  3. public   class  Test {  
  4.     public   static   void  main(String args[]) {  
  5.         ServiceImpl si = new  ServiceImpl();  
  6.   
  7.         ServiceHandler sh = new  ServiceHandler(si);  
  8.   
  9.         IService is = (IService) Proxy.newProxyInstance(si.getClass()  
  10.                 .getClassLoader(), si.getClass().getInterfaces(), sh);  
  11.   
  12.         is.getService("A" );  
  13.     }  
  14. }  
import java.lang.reflect.Proxy;

public class Test {
	public static void main(String args[]) {
		ServiceImpl si = new ServiceImpl();

		ServiceHandler sh = new ServiceHandler(si);

		IService is = (IService) Proxy.newProxyInstance(si.getClass()
				.getClassLoader(), si.getClass().getInterfaces(), sh);

		is.getService("A");
	}
}

 

二、CGLIB的动态代理类

 

CGLIB and  ASM

 
Figure 1: CGLIB Library and ASM Bytecode Framework 图一显示了和 CGLIB包和一些框架和语言的关系图。需要注意的是一些框架例如Spring AOP和Hibernate,它们为了满足需要经常同时使用JDK的动态代理和CGLIB包。Hiberater使用JDK的动态代理实现一个专门为 WebShere应用服务器的事务管理适配器;Spring AOP,如果不强制使用CGLIB包,默认情况是使用JDK的动态代理来代理接口。

 

Java代码
  1. public   class  Target {  
  2.   
  3.     public  String execute() {  
  4.         String message = "----------test()----------" ;  
  5.         System.out.println(message);  
  6.         return  message;  
  7.     }  
  8. }  
public class Target {

	public String execute() {
		String message = "----------test()----------";
		System.out.println(message);
		return message;
	}
}

 

Java代码
  1. import  net.sf.cglib.proxy.MethodInterceptor;  
  2. import  net.sf.cglib.proxy.MethodProxy;  
  3. import  java.lang.reflect.Method;  
  4.   
  5. public   class  MyMethodInterceptor  implements  MethodInterceptor {  
  6.   
  7.     public  Object intercept(Object object, Method method, Object[] args,  
  8.             MethodProxy methodProxy) throws  Throwable {  
  9.         System.out.println(">>>MethodInterceptor start..." );  
  10.         Object result = methodProxy.invokeSuper(object, args);  
  11.         System.out.println(">>>MethodInterceptor ending..." );  
  12.         return   "hahahh" ;  
  13.     }  
  14. }  
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

public class MyMethodInterceptor implements MethodInterceptor {

	public Object intercept(Object object, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		System.out.println(">>>MethodInterceptor start...");
		Object result = methodProxy.invokeSuper(object, args);
		System.out.println(">>>MethodInterceptor ending...");
		return "hahahh";
	}
}

 

Java代码
  1. import  net.sf.cglib.proxy.Enhancer;  
  2.   
  3. public   class  TestCglibProxy {  
  4.     public   static   void  main(String rags[]) {  
  5.         Target target = new  Target();  
  6.         TestCglibProxy test = new  TestCglibProxy();  
  7.         Target proxyTarget = (Target) test.createProxy(Target.class );  
  8.         String res = proxyTarget.execute();  
  9.         System.out.println(res);  
  10.     }  
  11.   
  12.     public  Object createProxy(Class targetClass) {  
  13.         Enhancer enhancer = new  Enhancer();  
  14.         enhancer.setSuperclass(targetClass);  
  15.         enhancer.setCallback(new  MyMethodInterceptor());  
  16.         return  enhancer.create();  
  17.     }  
  18. }  
import net.sf.cglib.proxy.Enhancer;

public class TestCglibProxy {
	public static void main(String rags[]) {
		Target target = new Target();
		TestCglibProxy test = new TestCglibProxy();
		Target proxyTarget = (Target) test.createProxy(Target.class);
		String res = proxyTarget.execute();
		System.out.println(res);
	}

	public Object createProxy(Class targetClass) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(targetClass);
		enhancer.setCallback(new MyMethodInterceptor());
		return enhancer.create();
	}
}

 

CGLIB包的基本代码很少,当学起来有一定的困难,主要是缺少文 档,这也是开源软件的一个不足之处。目前CGLIB的版本是(2.1.2),主要由一下部分组成:

net.sf.cglib.core
Low-level bytecode manipulation classes; Most of them are related to ASM.
net.sf.cglib.transform
Classes for class file transformations at runtime or build time
net.sf.cglib.proxy
Classes for proxy creation and method interceptions
net.sf.cglib.reflect
Classes for a faster reflection and C#-style delegates
net.sf.cglib.util
Collection sorting utilities
net.sf.cglib.beans
JavaBean related utilities

大多时候,仅仅为了动态地创建代理,你仅 需要使用到代理包中很少的一些API。

正如我们先前所讨论的,CGLIB包是在ASM之上的一个高级别的层。对代理那些没有实现接口的类 非常有用。本质上,它是通过动态的生成一个子类去覆盖所要代理类的不是final的方法,并设置好callback,则原有类的每个方法调用就会转变成调 用用户定义的拦截方法(interceptors),这比JDK动态代理方法快多了。

 

net.sf.cglib.proxy.MethodInterceptor 能够满足任何的拦截(interception )需要,当对有些情况下可能过度。为了简化和提高性能,CGLIB包提供了一些专门的回调(callback)类型。例如:

net.sf.cglib.proxy.FixedValue
为 提高性能,FixedValue回调对强制某一特别方法返回固定值是有用的。 net.sf.cglib.proxy.NoOp
NoOp回 调把对方法调用直接委派到这个方法在父类中的实现。 net.sf.cglib.proxy.LazyLoader
当 实际的对象需要延迟装载时,可以使用LazyLoader回调。一旦实际对象被装载,它将被每一个调用代理对象的方法使用。 net.sf.cglib.proxy.Dispatcher
Dispathcer 回调和 LazyLoader回调有相同的特点,不同的是,当代理方法 被调用时,装载对象的方法也总要被调用。 net.sf.cglib.proxy.ProxyRefDispatcher
ProxyRefDispatcher回调和 Dispatcher一样,不同的是,它可以把代理对象作为装载对象方法的一个参数传递。

 

代理类的所以方法经常会用到回调(callback),当是你 也可以使用net.sf.cglib.proxy.CallbackFilter 有选择的对一些方法使用回调(callback),这种考虑周详的控制特性在JDK的动态代理中是没有的。在JDK代理中,对 java.lang.reflect.InvocationHandler方法的调用对代理类的所以方法都有效。

 

Use a MethodInterceptor 为了更好的使用代理,我们可以使用自己定义的 MethodInterceptor 类型回调( callback )来代替 net.sf.cglib.proxy.NoOp 回调。当对代理中所有方法的调用时,都会转向 MethodInterceptor 类型的拦截( intercept )方法 , 在 拦截方法中再调用底层对象相应的方法。

 

Use a CallbackFilter

 

 

小结 GLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。 它底层使用字节码处理框架ASM。其原理是,生产一个要代理类的子类,子类覆盖要代理的类的所有不是final的方法。 它比使用java反射的JDK动态代理要快。通常情况下,你可以使用JDK的动态代理创建代理,当你要代理的类没有实现接口 或者为了更好的性能,CGLIB是一个好的选择。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值