好记忆不如烂笔头,能记下点东西,就记下点,有时间拿出来看看,也会发觉不一样的感受.
Java语言中的代理(Proxy)是一种重要的设计模式,它允许通过一个代理对象控制对目标对象的访问。代理模式的核心作用是提供间接层,常用于实现权限控制、延迟加载、日志记录等功能。

1. Cglib 代理的前世今生
-
诞生背景 :在 Java 开发中,有时需要对类进行增强或拦截,而 JDK 动态代理要求目标类必须实现接口。为了解决这一局限性,Cglib 应运而生。它通过字节码操作技术,动态生成目标类的子类来实现代理,无需目标类实现接口,从而在更广泛场景下满足动态代理需求。
-
发展历程 :早期版本的 Cglib 功能相对简单,随着 Java 技术的发展和应用场景的拓展,Cglib 不断优化和增强其功能,如提升性能、增加对更多 Java 版本的支持等。现在,Cglib 已经成为 Java 社区广泛使用的动态代理库之一,并且被许多知名框架集成,如 Spring AOP 在特定场景下会使用 Cglib 来实现更灵活的 AOP 功能。
2. Cglib 代理的核心设计思想
-
继承与增强 :Cglib 通过生成目标类的子类来实现代理,这个子类继承了目标类的所有方法,并可以对方法进行增强。在子类方法中,可以在执行目标方法之前或之后添加自定义逻辑,从而实现对目标类行为的扩展。
-
字节码操作 :利用 ASM 字节码操作库,Cglib 在运行时动态生成字节码,创建出目标类的代理子类。这种方式使得代理类能够直接与目标类的字节码进行交互,实现对方法的拦截和增强,无需借助接口,突破了 JDK 动态代理的限制,具有更高的灵活性和更广泛的应用场景。
-
回调机制 :Cglib 引入了回调机制,通过实现特定的回调接口(如
MethodInterceptor),可以在代理类的方法执行时,将控制权交给回调对象,从而实现自定义的代理逻辑。这使得代理行为的定义更加灵活,用户可以根据实际需求编写不同的回调逻辑来满足各种复杂的业务场景。
3. Cglib 代理的核心实现源码
-
Enhancer 类 :是 Cglib 的核心类,用于创建代理对象。它提供了设置父类、回调等方法,通过调用
create()方法生成代理对象。-
setSuperclass()方法用于设置要代理的目标类。 -
setCallback()方法用于设置回调对象,该对象定义了代理类中方法的拦截和增强逻辑。 -
create()方法是创建代理对象的关键入口,它会根据设置的参数动态生成代理类,并实例化代理对象。
-
-
MethodInterceptor 接口 :是一个常用的回调接口,它提供了一个
intercept()方法。当代理类的方法被调用时,会进入intercept()方法,在这里可以实现方法调用前后的逻辑以及对方法的拦截。 -
生成代理类字节码 :在
Enhancer的create()方法调用过程中,会利用 ASM 字节码操作库生成代理类的字节码。主要流程包括:-
确定代理类的父类和接口等基本信息。
-
生成代理类的字段、构造方法、普通方法等字节码内容。对于目标类的方法,会在代理类中生成相应的覆盖方法,并在方法内部调用回调对象的
intercept()方法来实现拦截和增强逻辑。import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(UserServiceImpl.class); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("CGLIB代理前置处理"); Object result = proxy.invokeSuper(obj, args); System.out.println("CGLIB代理后置处理"); return result; } }); UserService proxy = (UserService) enhancer.create(); proxy.saveUser("王五"); } }

-
4. 使用 Cglib 代理的使用场景
-
无接口的类增强 :当需要对没有实现接口的类进行功能增强时,Cglib 是一个很好的选择。例如,对一些第三方库中的类或遗留代码中的类进行功能扩展,而这些类又没有合适的接口可供使用。
-
性能敏感场景 :在对性能要求较高的场景中,Cglib 通常比 JDK 动态代理性能更好。因为它通过生成子类的字节码来实现代理,方法调用时不需要进行接口方法的反射调用,减少了反射带来的性能开销。
-
AOP 框架集成 :许多 AOP 框架(如 Spring AOP)在特定情况下会使用 Cglib 来实现更灵活的 AOP 功能。例如,当目标类没有实现接口或者需要对类的构造方法、字段访问等进行增强时,Cglib 可以提供更强大的支持。
-
服务代理与装饰器模式 :在实现服务代理或装饰器模式时,如果需要对类的行为进行增强,同时又不想修改原有类的代码结构,Cglib 代理可以方便地实现这一需求。

5. Cglib 代理的替代方案
-
JDK 动态代理 :适用于目标类实现了接口的场景,具有简单易用、与 Java 语言高度集成等优点。如果项目中的类大多实现了接口,且对性能要求不是极其苛刻,可以优先考虑使用 JDK 动态代理。
-
Spring AOP :是一个功能强大的 AOP 框架,它在底层集成了 JDK 动态代理和 Cglib 代理。开发人员可以根据实际情况,通过 Spring AOP 的配置来自动选择合适的代理方式,无需直接与底层代理技术打交道,提高了开发效率和代码的可维护性。

718

被折叠的 条评论
为什么被折叠?



