作者:
江南白衣 反射、Proxy和元数据是Java最强的三个特征,再加上
CGLib (Code Generation Library)和ASM,使得Java虽然没有Ruby,Python般后生可畏,一样能做出强悍的框架。
Proxy可以看作是微型的AOP,明白提供了在继承和委托之外的第三个代码封装途径,只要有足够的想象力,可以做得非常好玩,Spring的源码里用Proxy就用得很随便,看得我非常眼红。可惜Proxy必须基于接口。因此Spring的做法,基于接口的用proxy,否则就用cglib。AOP么,一般小事非compoent一级的就不麻烦AspectJ出手了。
cglib的Enhancer说起来神奇,用起来一页纸不到就讲完了。
它的原理就是用Enhancer生成一个原有类的子类,并且设置好callback到proxy, 则原有类的每个方法调用都会转为调用实现了MethodInterceptor接口的proxy的intercept()函数:
publicObjectintercept(Objecto,Methodmethod,Object[]args,MethodProxyproxy)
在intercept()函数里,你可以在执行Object result=proxy.invokeSuper(o,args);来执行原有函数,在执行前后加入自己的东西,改变它的参数值,也可以瞒天过海,完全干别的。说白了,就是AOP中的around advice。
AOP没有出现以前,该领域经典的设计模式是Decorator,像Java IO Stream的设计就是如此.不过,如果为每个DAO, 每个方法的写Decorator函数会写死人的,所以用上cglib的好处是一次过拦截所有方法。
另外,cglib除了Enhancer之外,还有BulkBean和Transform,都是Hibernate持久化的基础,但文档贫乏,一时还没去看怎么用。
1.AOP里讲了一百遍阿一百遍的log aspect在cglib是这样做的:
publicclassLogDAOProxyimplementsMethodInterceptor
{
privateLoggerlog=Logger.getLogger(LogDAOProxy.class);
privateEnhancerenhancer=newEnhancer();
//返回DAO的子类
publicObjectgetDAO(Classclz)
{
enhancer.setSuperclass(clz);
enhancer.setCallback(this);
returnenhancer.create();
}
//默认的拦截方法
publicObjectintercept(Objecto,Methodmethod,Object[]args,MethodProxyproxy)throwsThrowable
{
log.info("调用日志方法"+method.getName());
Objectresult=proxy.invokeSuper(o,args);
returnresult;
}
}
应用的代码:
LogDAOProxyproxy=newLogDAOProxy();
GoodsDAOdao=(GoodsDAO)proxy.getDAO(GoodsDAO.class);
dao.insert(goods);
2.而在Spring的管理下应该略加修改的高级Decorator
上面的例子用
returnenhancer.create();创建子类实例,但在Spring管理下,一些Bean的实例必须由Spring来创建和管理,而不由enhancer来创建的。所以我对上述用法略加修改,使它真正当一个Proxy的角色,请对比黑体字的部分
publicclassLogDAOProxyimplementsMethodInterceptor
{
privateLoggerlog=Logger.getLogger(LogDAOProxy.class);
privateObjectdao=null;
privateEnhancerenhancer=newEnhancer();
//返回DAO的子类
publicObjectgetDAO(Classclz,Objectdao)
{
this.dao=dao;
enhancer.setSuperclass(clz);
enhancer.setCallback(this);
returnenhancer.create();
}
//默认的拦截方法
publicObjectintercept(Objecto,Methodmethod,Object[]args,MethodProxyproxy)throwsThrowable
{
log.info("调用日志方法"+method.getName());
Objectresult=proxy.invoke(dao,args);
returnresult;
}
}
可见,原来模式里在getDao()时由enhancer创建dao,而调用intercept时则将enhancer创建的dao以Object o参数传回。
而新模式里,dao在getDao()时从外面传入,enhancer.create()返回的是一个proxy. 而调用intercept时,实际会用之前传入的dao进行操作,而忽略Object o参数传入的proxy.
有点遗憾, intercept函数里MethodProxy的Signature是固定的 , 即客户如果调用foo(String),你不可以用proxy.invoke偷换成foo(String,String);
系列文章:
Java下的框架编写(1)--序Java下的框架编程(2)-对泛型的无聊用法和为擦拭法站台Java下的框架编程(3)--关于反射的碎话Java下的框架编程(4)--Annotation vs XML vs Interface 最新一RoundJava下的框架编程(5)--cglib应用Java下的框架编程(6)--asm(待写)
分享到:
相关推荐
在这里,我们有两个版本,即cglib-full-2.0和cglib-full-2.0.2。通常,更新的版本修复了旧版本中的bug,可能提供了新的特性和性能优化。从2.0到2.0.2,可能会包含一些稳定性改进和兼容性调整。 5. **使用步骤** -...
CGLIB,全称为Code Generation Library,是一个强大的高性能的代码生成库,被广泛应用于Java世界,尤其是Spring框架中。它允许程序在运行时动态地创建Java对象并扩展已有类的功能。CGLIB是通过字节码技术实现的,而...
在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者将关注点从核心业务逻辑中分离出来,例如日志记录、事务管理等。在本篇Spring学习笔记中,我们将探讨如何使用CGLIB库来实现AOP功能。 CGLIB...
总的来说,`spring-cglib-repack-3.2.0.jar`和`spring-objenesis-repack-2.1.jar`是Spring框架正常运行的关键组成部分,它们分别负责动态子类生成和无参构造函数对象的快速实例化,对于理解和优化Spring应用的性能有...
在Java开发领域,Spring框架是不可或缺的一个部分,它极大地简化了企业级应用的开发工作。在深入学习和分析Spring源码时,有时我们需要一个完整的运行环境来理解其内部机制。"spring-cglib-repack-3.2.5.jar"、...
Spring框架是Java开发中广泛应用的一个开源框架,它极大地简化了企业级应用的开发工作。在提供的文件中,我们看到了两个与Spring相关的库:`spring-cglib-repack-3.2.6.jar` 和 `spring-objenesis-repack-2.6.jar`。...
在Java开发领域,Spring框架是应用最广泛的轻量级框架之一,它提供了全面的基础设施支持,使得开发者可以更轻松地创建企业级应用。在深入理解`spring-cglib-repack-3.2.4.jar`和`spring-objenesis-repack-2.5.1.jar`...
标题中的"spring-cglib-repack-3.2.5.jar"和"spring-objenesis-repack-2.6.jar"是两个与Spring框架相关的库文件,它们主要用于Spring框架的内部实现,尤其是针对Java对象的创建和代理机制。下面将详细解释这两个库的...
Spring框架是Java开发中不可或缺的一部分,它提供了丰富的功能来简化企业级应用的开发。在给定的标题和描述中,提到了两个关键的jar包:`spring-cglib-repack-3.2.6.jar` 和 `spring-objenesis-repack-2.6.jar`。这...
CGLIB是一个高性能的代码生成库,它在许多Java框架中被广泛使用,如Spring AOP。CGLIB能够生成子类,从而实现对目标类的代理。在Spring中,当一个类没有实现接口时,Spring会使用CGLIB来创建代理对象,以便在不修改...
在IT行业中,Spring框架是Java开发中的一个核心组件,它为构建企业级应用程序提供了全面的解决方案。Spring框架以其模块化、灵活的设计和丰富的功能而受到广大开发者喜爱。当我们深入研究Spring框架的源码时,了解其...
在Java开发领域,Spring框架是不可或缺的一个部分,它为构建企业级应用提供了强大的支持。当我们在研究或编译Spring 4.0的源码时,可能会遇到一些依赖问题,其中"spring-cglib-repack-3.1.jar"和"spring-objenesis-...
其次,`cglib-2.2`是CGLIB(Code Generation Library)的一个版本,这是一个Java字节码生成库。它主要用于运行时动态创建类和方法,尤其在AOP(面向切面编程)和ORM(对象关系映射)框架中广泛应用。CGLIB的主要特性...
Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单...
Spring框架是Java开发中不可或缺的一部分,它为应用程序提供了一种模块化、面向接口的编程模型。在本场景中,我们关注的是两个特定的jar包——"spring-cglib-repack-3.2.5.jar" 和 "spring-objenesis-repack-2.5.1....
在Java开发中,CGLib是一个不可或缺的工具,尤其在AOP(面向切面编程)和ORM(对象关系映射)等领域广泛应用。 `cglib-nodep-2.2.jar` 和 `cglib-2.2.0.jar` 是CGLib的两个不同版本。`nodep` 在这里表示 "no ...
总之,`spring-cglib-repack-3.2.4.jar`和`spring-objenesis-repack-2.4.jar`在Spring框架中扮演着核心角色,主要负责AOP代理和复杂对象的实例化。了解这些库的作用和使用方法,有助于更好地理解和优化Spring应用。
在Spring框架中,`spring-cglib-repack-3.2.6.jar`和`spring-objenesis-repack-2.6.jar`是两个重要的依赖库,它们在Spring源码环境中扮演着不可或缺的角色。本文将详细介绍这两个库以及它们在Spring框架中的作用。 ...
《深入理解Hibernate-CGLIB-2.1_3在Java开发中的应用》 在Java开发领域,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。而CGLIB则是一个代码生成库,它允许开发者在运行时动态创建子类...
在Java开发领域,Spring框架是应用最广泛的轻量级框架之一,它提供了全面的基础设施支持,使得开发者可以更高效地构建企业级应用。在Spring框架的运作过程中,有时会遇到由于类加载器或依赖冲突导致的问题,特别是...