cglib

CGLIB(Code Generation Library)是一个开源项目!
是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。Hibernate用它来实现PO(Persistent Object 持久化对象) 字节码的动态生成。

1CGLIB包的介绍编辑

代理为控制要访问的目标对象提供了一种途径。当访问对象时,它引入了一个间接的层。JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理。JDK的动态代理用起来非常简单,但它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,该怎么办?现在我们可以使用CGLIB包
CGLIB是一个强大的高性能的 代码生成包。它广泛的被许多AOP的 框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。最流行的OR Mapping工具hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其他机制实现的)。EasyMock和 jMock是通过使用模仿(moke)对象来测试java代码的包。它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。
CGLIB包的底层是通过使用一个小而快的 字节码处理框架ASM,来转换字节码并生成新的类。除了CGLIB包, 脚本语言例如Groovy和BeanShell,也是使用ASM来生成java的 字节码。当然不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。

2cglib代码包结构编辑

  • core (核心代码)
    • EmitUtils
    • ReflectUtils
    • KeyFactory
    • ClassEmitter/CodeEmitter
    • NamingPolicy/DefaultNamingPolicy
    • GeneratorStrategy/DefaultGeneratorStrategy
    • DebuggingClassWriter
    • ClassGenerator/AbstractClassGenerator
  • beans (bean操作类)
    • BeanCopier
    • BulkBean
    • BeanMap
    • ImmutableBean
    • BeanGenerator
  • reflect
    • FastClass
  • proxy
    • MethodInterceptor , Dispatcher, LazyLoader , ProxyRefDispatcher , NoOp , FixedValue , InvocationHandler(提供和jdk proxy的功能)
    • Enhancer
    • CallbackGenerator
    • Callback
    • CallbackFilter
  • util
    • StringSwitcher
    • ParallelSorter
  • transform
### CGLIB 的功能 CGLIB(Code Generation Library)是一个强大的字节码生成库,能够在运行动态地生成目标子类,从而实现代理功能。其核心功能是通过继承目标来创建代理对象,因此可以用于对没有实现接口的进行代理。与 JDK 动态代理不同,CGLIB 不依赖接口,而是通过操作字节码来实现对增强CGLIB 的代理机制主要依赖于 `Enhancer` ,它能够为指定创建子类子类中拦截对父方法的调用,从而实现诸如日志记录、事务管理等功能。CGLIB使用了 `FastClass` 机制,使得方法调用的性能优于传统的反射调用[^3]。 --- ### CGLIB使用场景 CGLIB使用场景主要括以下几种情况: - **目标没有实现接口**:JDK 动态代理要求目标必须实现至少一个接口,而 CGLIB 可以对任意进行代理,因此在目标未实现接口CGLIB 是唯一的选择。 - **需要代理非接口方法**:CGLIB 通过继承机制代理中的方法,因此可以代理非接口定义的方法。 - **需要代理 final 或方法**:虽然 CGLIB 无法代理 `final` 或 `final` 方法,但在某些特定场景下,可以通过配置或修改结构来规避这一限制。 - **需要更高的性能**:CGLIB 的 `FastClass` 机制避免了反射调用的开销,因此在对性能要求较高的场景下,CGLIB 比 JDK 动态代理更具优势[^1]。 - **强制使用基于的代理**:在 Spring 配置中,可以通过设置 `proxy-target-class="true"` 强制使用 CGLIB 代理,即使目标实现了接口。 --- ### CGLIB 与 Spring 的关系 Spring 框架广泛使用 CGLIB 来实现 AOP(面向切面编程)功能。Spring AOP 默认使用 JDK 动态代理,但当目标对象没有实现任何接口,Spring 会自动切换到 CGLIB 代理。此外,Spring 允许通过配置强制使用 CGLIB 代理,以确保代理逻辑的一致性。 Spring 在内部通过 `Enhancer` 创建代理对象,结合 `MethodInterceptor` 接口来拦截方法调用。Spring AOP 利用 CGLIB字节码增强能力,在方法调用前后插入切面逻辑,例如事务管理、日志记录等。 Spring Boot 2.x 中默认使用 CGLIB 而不再使用 JDK 动态代理,主要是因为 CGLIB 的灵活性和性能优势。JDK 动态代理依赖于接口,而 Spring Boot 的设计倾向于更通用的代理方式,CGLIB 能够满足这一需求。 --- ### 示例代码:使用 CGLIB 创建代理 ```java import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CglibProxyExample { static class TargetClass { public void sayHello() { System.out.println("Hello from target class!"); } } static class MyMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("Before method: " + method.getName()); Object result = proxy.invokeSuper(obj, args); System.out.println("After method: " + method.getName()); return result; } } public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(TargetClass.class); enhancer.setCallback(new MyMethodInterceptor()); TargetClass proxy = (TargetClass) enhancer.create(); proxy.sayHello(); } } ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值