`
bolan392
  • 浏览: 276791 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

CGLIB简介

 
阅读更多

CGlib是什么? 
CGlib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。 
当然这些实际的功能是asm所提供的,asm又是什么?Java字节码操控框架,具体是什么大家可以上网查一查,毕竟我们这里所要讨论的是cglib, 
cglib就是封装了asm,简化了asm的操作,实现了在运行期动态生成新的class。 
可能大家还感觉不到它的强大,现在就告诉你。 
实际上CGlib为spring aop提供了底层的一种实现;为hibernate使用cglib动态生成VO/PO (接口层对象)。 

下面我们将通过一个具体的事例来看一下CGlib体验一下CGlib。 
* CGlib 2.13 
* ASM 2.23 
以一个实例在简单介绍下cglib的应用。 
我们模拟一个虚拟的场景,模拟对表的操作。 
1. 开始我们对表提供了CRUD方法。 
我们现在创建一个对Table操作的DAO类。 

Java代码  收藏代码
  1. public class TableDAO {  
  2.     public void create(){  
  3.         System.out.println("create() is running !");  
  4.     }  
  5.     public void query(){  
  6.         System.out.println("query() is running !");  
  7.     }  
  8.     public void update(){  
  9.         System.out.println("update() is running !");  
  10.     }  
  11.     public void delete(){  
  12.         System.out.println("delete() is running !");  
  13.     }  
  14. }  


OK,它就是一个javaBean,提供了CRUD方法的javaBean。 
下面我们创建一个DAO工厂,用来生成DAO实例。 

Java代码  收藏代码
  1. public class TableDAOFactory {  
  2.     private static TableDAO tDao = new TableDAO();  
  3.     public static TableDAO getInstance(){  
  4.         return tDao;  
  5.     }  
  6. }  


接下来我们创建客户端,用来调用CRUD方法。 

Java代码  收藏代码
  1. public class Client {  
  2.   
  3.     public static void main(String[] args) {  
  4.         TableDAO tableDao = TableDAOFactory.getInstance();  
  5.         doMethod(tableDao);  
  6.     }  
  7.     public static void doMethod(TableDAO dao){  
  8.         dao.create();  
  9.         dao.query();  
  10.         dao.update();  
  11.         dao.delete();  
  12.     }  
  13. }  


OK,完成了,CRUD方法完全被调用了。当然这里并没有CGlib的任何内容。问题不会这么简单的就结束,新的需求来临了。 
2. 变化随之而来,Boss告诉我们这些方法不能开放给用户,只有“张三”才有权使用。阿~!怎么办,难道我们要在每个方法上面进行判断吗? 
好像这么做也太那啥了吧,对了对了Proxy可能是最好的解决办法。jdk的代理就可以解决了。 好了我们来动手改造吧。等等jdk的代理需要实现接口,这样, 
我们的dao类需要改变了。既然不想改动dao又要使用代理,我们这就请出CGlib。 
我们只需新增一个权限验证的方法拦截器。 

Java代码  收藏代码
  1. public class AuthProxy implements MethodInterceptor {  
  2.     private String name ;  
  3.     //传入用户名称  
  4.     public AuthProxy(String name){  
  5.         this.name = name;  
  6.     }  
  7.     public Object intercept(Object arg0, Method arg1, Object[] arg2,  
  8.             MethodProxy arg3) throws Throwable {  
  9.         //用户进行判断  
  10.         if(!"张三".equals(name)){  
  11.             System.out.println("你没有权限!");  
  12.             return null;  
  13.         }  
  14.         return arg3.invokeSuper(arg0, arg2);  
  15.     }  
  16. }  


当然不能忘了对我们的dao工厂进行修改,我们提供一个使用代理的实例生成方法 

Java代码  收藏代码
  1. public static TableDAO getAuthInstance(AuthProxy authProxy){  
  2.     Enhancer en = new Enhancer();  
  3.     //进行代理  
  4.     en.setSuperclass(TableDAO.class);  
  5.     en.setCallback(authProxy);  
  6.     //生成代理实例  
  7.     return (TableDAO)en.create();  
  8. }  


我们这就可以看看客户端的实现了。添加了两个方法用来验证不同用户的权限。 

Java代码  收藏代码
  1. public static void haveAuth(){  
  2.     TableDAO tDao = TableDAOFactory.getAuthInstance(new AuthProxy("张三"));  
  3.     doMethod(tDao);  
  4. }  
  5. public static void haveNoAuth(){  
  6.     TableDAO tDao = TableDAOFactory.getAuthInstance(new AuthProxy("李四"));  
  7.     doMethod(tDao);  
  8. }  


OK,"张三"的正常执行,"李四"的没有执行。 
看到了吗?简单的aop就这样实现了 
难道就这样结束了么? 
3. Boss又来训话了,不行不行,现在除了"张三"其他人都用不了了,现在不可以这样。他们都来向我反映了,必须使用开放查询功能。 
哈哈,现在可难不倒我们了,因为我们使用了CGlib。当然最简单的方式是去修改我们的方法拦截器,不过这样会使逻辑变得复杂,且 
不利于维护。还好CGlib给我们提供了方法过滤器(CallbackFilter),CallbackFilte可以明确表明,被代理的类中不同的方法, 
被哪个拦截器所拦截。下面我们就来做个过滤器用来过滤query方法。 

Java代码  收藏代码
  1. public class AuthProxyFilter implements CallbackFilter{  
  2.     public int accept(Method arg0) {  
  3.         if(!"query".equalsIgnoreCase(arg0.getName()))  
  4.             return 0;  
  5.         return 1;  
  6.     }  
  7.   
  8. }  


OK,可能大家会对return 0 or 1感到困惑,用到的时候就会讲解,当然下面就会用到了。 
我们在工场中新增一个使用了过滤器的实例生成方法。 

Java代码  收藏代码
  1. public static TableDAO getAuthInstanceByFilter(AuthProxy authProxy){  
  2.     Enhancer en = new Enhancer();  
  3.     en.setSuperclass(TableDAO.class);  
  4.     en.setCallbacks(new Callback[]{authProxy,NoOp.INSTANCE});  
  5.     en.setCallbackFilter(new AuthProxyFilter());  
  6.     return (TableDAO)en.create();  
  7. }  


看到了吗setCallbacks中定义了所使用的拦截器,其中NoOp.INSTANCE是CGlib所提供的实际是一个没有任何操作的拦截器, 
他们是有序的。一定要和CallbackFilter里面的顺序一致。明白了吗?上面return返回的就是返回的顺序。也就是说如果调用query方法就使用NoOp.INSTANCE进行拦截。 
现在看一下客户端代码。 

Java代码  收藏代码
  1. public static void haveAuthByFilter(){  
  2.     TableDAO tDao = TableDAOFactory.getAuthInstanceByFilter(new AuthProxy("张三"));  
  3.     doMethod(tDao);  
  4.   
  5.     tDao = TableDAOFactory.getAuthInstanceByFilter(new AuthProxy("李四"));  
  6.     doMethod(tDao);  
  7. }  


ok,现在"李四"也可以使用query方法了,其他方法仍然没有权限。 
哈哈,当然这个代理的实现没有任何侵入性,无需强制让dao去实现接口。 

分享到:
评论

相关推荐

    转载:cglib动态代理介绍(一)

    ### CGlib简介 CGlib(Code Generation Library)是一个强大的高性能的代码生成库,它在运行期扩展Java类与实现Java接口。CGlib是通过在运行时生成字节码来实现动态代理的。它不是直接对Java字节码进行操作,而是...

    cglib动态代理

    #### 一、cglib简介 cglib(Code Generation Library)是一个功能强大、性能高效且质量卓越的代码生成类库。它能够在程序运行时动态地扩展Java类并实现Java接口,其核心是利用ASM(Another Small Machine)框架来...

    cglib-3.1.rar

    一、CGlib简介 CGlib是基于ASM库的一个高性能的代码生成库,它的主要功能是能够在运行时动态地创建类的子类或增强已有类的功能。与Java的反射机制相比,CGlib通过字节码技术提供了更快的访问速度,尤其在处理大量...

    cglib使用

    **CGlib简介** CGlib(Code Generation Library)是一个强大的、高性能的代码生成库,它在运行期扩展Java类与实现Java接口。CGlib是通过字节码技术来实现的,它底层利用了ASM库来操作字节码。CGlib常被用于动态代理...

    Spring cglib 中文说明

    #### CGLIB 包简介与原理 CGLIB(Code Generation Library)是一个强大且高性能的代码生成库。它在众多面向切面编程(AOP)框架中扮演着核心角色,例如Spring AOP、Dynaop等。此外,它还被广泛应用于ORM(Object-...

    Hibernate底层技术简介 CGLIB

    在Hibernate的底层实现中,CGLIB(Code Generation Library)起到了至关重要的作用。CGLIB是一个代码生成库,它基于ASM库,但提供了更高级别的抽象和更加便捷的API。 首先,CGLIB扩展了ASM的Visitor模式。ASM是一个...

    Spring定时器与动态代理实例

    - **CGLIB简介**:CGLIB是一个强大的高性能的代码生成库,它在许多AOP框架中被使用,例如Spring AOP和dynaop,为他们提供方法的动态代理。 - **生成代理对象**:通过CGLIB的Enhancer类,我们可以创建一个代理类,...

    Java JDK代理、CGLIB、AspectJ代理分析比较

    #### 一、代理模式简介 代理模式是一种常见的设计模式,在《Design Patterns in Java》一书中对其有明确的定义:“代理模式为一个对象提供一个代理,以控制对该对象的访问。”简而言之,代理模式允许我们在不修改...

    SpringAOP的实现机制(底层原理)、应用场景等详解,模拟过程的实例

    简介: 本资源将深入探讨Spring框架中使用的两种关键的动态代理方式:JDK动态代理和CGLib动态代理。这两种代理方式在Spring AOP中起到关键作用,用于实现横切关注点的切面编程。通过学习它们的原理和实际应用,您将...

    Spring框架+Spring工作原理+AOP面向切面编程+JDK代理+Cglib代理

    #### 一、Spring框架简介 Spring框架是一个广泛使用的开源Java平台,用于构建高质量的企业级应用程序。它最初由Rod Johnson在2004年创建,旨在简化企业级Java应用程序的开发过程。Spring的核心优势在于它的轻量级...

    asm4开发手册-英文原版

    在手册的【部分内容】中,提供了ASM4.0的简介以及一些关键点,比如: - ASM4.0是一个Java字节码工程库,用于在Java环境下对Java类的字节码进行分析和转换。 - 该库由Eric Bruneton创建,受到版权限制,使用时需要...

    基于SpringBoot、Spring表达式语言 (SpEL)、annotation的操作日志框架+源代码+文档说明

    ### 简介 * 使用annotation来标注方法,标记操作内容 * 使用SpEL来动态生成操作日志内容,使操作日志记录更加详细(记录操作内容ID等关键信息) * 同一个方法,不同类型用户(admin,user等)使用时,获取不同的操作...

    Spring AOP切面编程简介

    **Spring AOP切面编程简介** 在Java世界中,Spring框架是企业级应用开发的首选,其中AOP(Aspect Oriented Programming,面向切面编程)是其重要特性之一。AOP提供了一种将关注点分离的技术,使得我们可以将一些...

    Java 动态代理.md

    #### 代理模式简介 代理模式是 23 种设计模式之一,属于结构型设计模式。其核心思想是提供一个代理来控制对某个对象的访问,以便于在不修改原始对象的前提下为其增加新的功能或操作。通过这种方式,可以在目标对象...

    Video基础知识简介

    3. **代理**:Spring支持JDK动态代理和CGLIB代理,用于实现AOP的功能,使得可以在不修改原有代码的情况下,增强对象的行为。 4. **Bean生命周期**:Spring管理的Bean有创建、初始化、使用和销毁等阶段,可以通过配置...

    org.springframework.asm-3.0.5.RELEASE.jar

    一、ASM库简介 ASM是一个轻量级的Java字节码操控和分析框架,它可以直接生成和读取Java类的字节码。ASM提供了一种低级别的接口,允许开发者创建、修改和分析类或对象。在Spring框架中,ASM主要用于AOP(面向切面...

    AOP简介基础入门

    前者针对接口实现,后者针对类实现,如果目标对象没有接口,Spring会使用CGLIB生成代理。 切入点表达式支持多种模式,例如: - `execution(* *(*))`匹配任何公共方法。 - `execution(* set*(*))`匹配任何以"set...

Global site tag (gtag.js) - Google Analytics