1. 反射机制
- 定义:反射是 Java 语言提供的一种基础功能,允许程序在运行时自省(
introspect
),直接操作类或对象。 - 功能:
- 获取类定义、属性和方法。
- 调用方法或构造对象。
- 运行时修改类定义。
- 应用场景:
O/R Mapping
框架:通过反射自动生成setter
和getter
,简化数据加载和持久化。- 绕过
API
访问控制:使用反射绕开访问限制,例如释放DirectBuffer
。
- 限制:Java 9 引入模块化系统后,对反射访问进行了限制,需要显式声明模块间的访问权限。
2. 动态代理
- 定义:动态代理是一种运行时动态构建代理对象、处理代理方法调用的机制。
- 应用场景:
- 包装
RPC
调用。 - 面向切面编程(
AOP
)。
- 包装
- 实现方式:
JDK
动态代理:基于反射机制实现,要求目标对象实现接口。cglib
动态代理:基于字节码操作机制(如 ASM)实现,通过创建目标类的子类来实现代理。
3. JDK 动态代理
- 优势:
- 最小化依赖关系,减少开发和维护工作量。
- 平滑进行 JDK 版本升级。
- 实现简单。
- 限制:以接口为中心,要求目标对象实现接口,适用范围有限。
4. cglib 动态代理
- 优势:
- 不依赖接口,适用于没有实现接口的目标对象。
- 高性能。
- 实现方式:通过创建目标类的子类实现代理。
5. 动态代理 vs CGLIB
特性 | 动态代理 | CGLIB |
---|---|---|
代理方式 | 基于接口 | 基于类继承 |
性能 | 反射调用较慢 | 通过ASM生成字节码,性能更高 |
依赖 | JDK原生支持 | 需要引入第三方库 |
方法限制 | 只能代理接口方法 | 可代理类中的非final方法 |
6. 选择动态代理实现的依据
- 可靠性:
JDK
动态代理更加可靠,因为它是 JDK 自带的功能。 - 可维护性:
JDK
动态代理的代码实现简单,易于维护。 - 性能:虽然
cglib
在某些场景下性能更高,但在大多数情况下,JDK
动态代理的性能已经足够。 - 适用性:如果目标对象实现了接口,优先选择
JDK
动态代理;如果没有实现接口,可以考虑cglib
。
7. AOP 与动态代理
- AOP(面向切面编程):通过动态代理机制,将通用逻辑(如日志、事务、安全等)与业务逻辑分离,提高代码的抽象程度和复用度。
- 应用场景:日志记录、事务管理、用户鉴权、性能监控等。
8. 总结
- 反射机制:赋予了 Java 语言运行时自省的能力,是动态代理的基础。
- 动态代理:通过代理机制,可以优雅地解决繁琐的重复编程问题,广泛应用于
RPC
、AOP
等场景。 - 实现方式:
JDK
动态代理和cglib
动态代理各有优势,选择时需要综合考虑可靠性、可维护性、性能和适用性。