CGLIB - dynamic bytecode generation

原创 2007年10月14日 19:28:00

CGLIB - dynamic bytecode generation

关键字:   cglib    

CGLIB (Code Generation Library) 是一个动态字节码生成库, 基于ASM, 使用时需要asm.jar。(Groovy也是使用ASM来生成java的字节码)

使用java的java.lang.reflect.Proxy只能针对接口生成代理; 而使用CGLIB则可以针对类生成代理. CGLIB原理是在运行时动态生成一个被代理类的子类。

下面的例子使用CGLIB, 对服务层对象的方法进行拦截,实现一个类似的AOP.

java 代码
  1. public class ProductService implements ServiceInterface  {   
  2.        
  3.     public void doDelete(Integer id) {   
  4.         productDAO.delete(id);   
  5.     }   
  6.   
  7.     public void doSave(ProductDTO dto) {   
  8.         productDAO.saveOrUpdate(dto);   
  9.     }   
  10.   
  11.     public void doUpdate(ProductDTO dto) {   
  12.         productDAO.saveOrUpdate(dto);   
  13.     }   
  14.   
  15.     public ProductDTO getObject(Integer id) {   
  16.         return productDAO.getProduct(id);   
  17.     }   
  18. }  

ProductService是一个简单的服务层类, 在ServiceInterface中定义了DAO对象和一些方法。

如果服务层对象有事物方面的需要, 就使用Interceptor来增强. 需要实现 net.sf.cglib.proxy.MethodInterceptor 接口.

java 代码
  1. public class ServiceMethodInterceptor implements MethodInterceptor {   
  2.        
  3.     private static final Logger logger = Logger.getLogger(ServiceMethodInterceptor.class);   
  4.   
  5.     public Object intercept(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable {   
  6.   
  7.         if (method == null || StringUtils.isBlank(method.getName())) {   
  8.             logger.error("Method is null!");   
  9.             return null;   
  10.         }   
  11.         String methodName = method.getName();   
  12.            
  13.         //所有以do开头的方法,使用updateTransaction   
  14.         if (methodName.startsWith("do")) {   
  15.             return updateTransaction(o, method, args, proxy);   
  16.         }   
  17.            
  18.         //所有以get开头的方法,使用queryTransaction   
  19.         if (methodName.startsWith("get")) {   
  20.             return queryTransaction(o, method, args, proxy);   
  21.         }   
  22.            
  23.         return proxy.invokeSuper(o,args);   
  24.     }   
  25.        
  26.     private Object queryTransaction(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable {   
  27.   
  28.         Object result = null;   
  29.         try{   
  30.             result = proxy.invokeSuper(o,args);   
  31.         } catch (Exception e) {   
  32.             logger.fatal(e);   
  33.         }  finally {   
  34.             TransactionBO.endSession();   
  35.         }   
  36.            
  37.         return result;   
  38.     }   
  39.        
  40.     private Object updateTransaction(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable {   
  41.            
  42.         Object result = null;   
  43.         try{   
  44.             TransactionBO.beginTransaction();   
  45.             result = proxy.invokeSuper(o,args);   
  46.             TransactionBO.commit();   
  47.         } catch (Exception e) {   
  48.             TransactionBO.rollback();   
  49.         }  finally {   
  50.             TransactionBO.endSession();   
  51.         }   
  52.            
  53.         return result;   
  54.     }   
  55.   
  56. }  
java 代码
  1. public class ServiceFactory {   
  2.        
  3.     public static extends ServiceInterface> T getServiceInstance(Class clazz) {   
  4.         Enhancer enhancer = new Enhancer();   
  5.         enhancer.setSuperclass(clazz);   
  6.         enhancer.setCallback(new ServiceMethodInterceptor());   
  7.         return (T) enhancer.create();   
  8.     }   
  9. }  

使用ProductService时,需要由ServiceFactory创建

java 代码
  1. public static void main(String[] args) {   
  2.     ProductService productService = ServiceFactory.getServiceInstance(ProductService.class);   
  3.     productService.doSave(...);   
  4.     productService.getObject(...);   
  5. }  

实际上这里使用的是CGLIB生成的ProductService的子类.  Enhancer生成的子类都实现了net.sf.cglib.proxy.Factory接口, 可以通过Factory.getCallbacks()取回MethodInterceptor

参考

http://cglib.sourceforge.net/

http://asm.objectweb.org/

http://www.javaeye.com/topic/98178

http://www.blogjava.net/calvin/archive/2005/11/28/21741.html

http://www-128.ibm.com/developerworks/cn/java/j-dyn0414/index.html

 

Java动态代理模式jdk和cglib的2种实现以及二者的区别(AOP面向切面的前奏)

关于动态代理模式里面有两种实现,一种是jdk实现,一种是cglib来实现。 下面来整jdk来实现动态代理的Java实例。 jdk动态代理模式里面有个拦截器的概念,在jdk中,只要实现了Invocati...
  • qq_27093465
  • qq_27093465
  • 2016年11月25日 21:40
  • 2633

通过dalvik code的解释执行了解dalvik bytecode结构

参考Java代码            public int Test1(int arg) {                    returnaurora.view.AuroraTest...
  • oman111
  • oman111
  • 2014年10月22日 17:42
  • 821

使用CGLIB实现AOP功能与AOP概念解释

使用CGLIB实现AOP功能在Java里面,我们要产生某个对象的代理对象,这个对象必须要有一个特点,即这个对象必须实现一个接口,动态代理技术只能基于接口进行代理。有时候我们在做开发的时候,这个对象就没...
  • yerenyuan_pku
  • yerenyuan_pku
  • 2016年10月19日 22:38
  • 1516

Spring的两种代理JDK和CGLIB的区别浅谈

一、原理区别: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。 而cglib动态代理是利用asm开源包,对代理对象类的cla...
  • u013126379
  • u013126379
  • 2016年08月04日 17:39
  • 17512

内存代管理器TenuredGeneration对垃圾对象的回收

内存代管理器TenuredGeneration作为基于内存分代管理的内存堆管理器GenCollectedHeap默认的旧生代管理器,它对垃圾对象的回收算法要比年青代Gc要复杂的多,但其主体思路就是:标...
  • xhh198781
  • xhh198781
  • 2015年01月18日 15:57
  • 2089

CGLib动态代理原理及实现

JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采...
  • yakoo5
  • yakoo5
  • 2013年06月15日 00:01
  • 49298

AOP CGLIB 是采用 继承方式 进行代理的

如果在配置文件中配置了: 而且在代码中设置了 @Aspect @AfterReturning(value="execution(* com.tfdd.service..*.*(..))", retur...
  • NBA_2011
  • NBA_2011
  • 2016年08月09日 15:08
  • 529

好记性不如烂笔头47-java拦截器-用CGLib实现动态代理(2)

动态代理技术是整个java技术系统中非常重要的一环,它是我们能够深入学习java框架的基础,是深入了解Spring等框架时要掌握的基础知识之一。 Java中自带的动态代理的类必须要实现一个接口,也就...
  • ffm83
  • ffm83
  • 2015年02月10日 13:59
  • 1480

CGLib动态代理的介绍及用法(单回调、多回调、不处理、固定值、懒加载)

前面介绍了代理模式,讲了动态代理常见的实现方式,包含了JDK的动态代理和CGLib的动态代理。本文将介绍下CGLib动态代理及几种用法。CGLib(Code Generation Library)...
  • difffate
  • difffate
  • 2017年04月24日 01:21
  • 449

java字节码理解——Java bytecode:翻译和解读

道新闻 2017-03-25 08:26 本篇博客是对Java bytecode:这篇文章的翻译和解读,原文链接在这 http://www.ibm.com/developerworks/lib...
  • u011277123
  • u011277123
  • 2017年03月30日 14:29
  • 682
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CGLIB - dynamic bytecode generation
举报原因:
原因补充:

(最多只允许输入30个字)