【Java学习】动态代理有哪些形式?

Java动态代理的两种主要形式

动态代理在Java中有两种主要的实现方式,它们各有特点和使用场景:

1. JDK动态代理 (基于接口)

特点

  • Java标准库自带的功能(java.lang.reflect.Proxy
  • 只能代理接口,不能代理普通类
  • 运行时动态生成代理类
  • 性能较好

使用场景

  • 当你的类已经实现了接口时
  • Spring AOP默认使用这种方式

示例代码

java 复制代码
// 接口
interface UserService {
    void saveUser();
}

// 实现类
class UserServiceImpl implements UserService {
    public void saveUser() {
        System.out.println("保存用户");
    }
}

// 创建代理
UserService proxy = (UserService) Proxy.newProxyInstance(
    UserService.class.getClassLoader(),
    new Class[]{UserService.class},
    (proxyObj, method, args) -> {
        System.out.println("前置处理");
        Object result = method.invoke(new UserServiceImpl(), args);
        System.out.println("后置处理");
        return result;
    }
);

proxy.saveUser();

2. CGLIB动态代理 (基于继承)

特点

  • 需要引入第三方库(cglib)
  • 可以代理普通类,不要求有接口
  • 通过继承目标类并重写方法实现代理
  • 生成速度比JDK代理稍慢,但执行效率高

使用场景

  • 当要代理的类没有实现接口时
  • Spring AOP当目标类没有接口时自动使用CGLIB

示例代码

java 复制代码
// 普通类(没有接口)
class ProductService {
    public void addProduct() {
        System.out.println("添加产品");
    }
}

// 创建代理
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(ProductService.class);
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
    System.out.println("前置处理");
    Object result = proxy.invokeSuper(obj, args);
    System.out.println("后置处理");
    return result;
});

ProductService proxy = (ProductService) enhancer.create();
proxy.addProduct();

两种方式的对比

特性 JDK动态代理 CGLIB动态代理
实现方式 基于接口 基于继承
是否需要接口 必须 不需要
性能 生成快,调用稍慢 生成慢,调用快
限制 只能代理接口方法 不能代理final类/方法
依赖 Java内置 需要第三方库

如何选择?

  1. 如果目标对象有接口,优先用JDK动态代理(Spring默认策略)
  2. 如果目标对象没有接口,只能用CGLIB
  3. 对性能要求极高时,可以考虑CGLIB
  4. 需要代理final方法时,只能用JDK动态代理

现代框架如Spring会根据情况自动选择最合适的代理方式。

相关推荐
2301_8050545612 分钟前
Python训练营打卡Day59(2025.7.3)
开发语言·python
snoopyfly~13 分钟前
Ubuntu 24.04 LTS 服务器配置:安装 JDK、Nginx、Redis。
java·服务器·ubuntu
万千思绪37 分钟前
【PyCharm 2025.1.2配置debug】
ide·python·pycharm
挺菜的38 分钟前
【算法刷题记录(简单题)003】统计大写字母个数(java代码实现)
java·数据结构·算法
Chef_Chen1 小时前
从0开始学习计算机视觉--Day07--神经网络
神经网络·学习·计算机视觉
掘金-我是哪吒1 小时前
分布式微服务系统架构第156集:JavaPlus技术文档平台日更-Java线程池使用指南
java·分布式·微服务·云原生·架构
亲爱的非洲野猪2 小时前
Kafka消息积压的多维度解决方案:超越简单扩容的完整策略
java·分布式·中间件·kafka
wfsm2 小时前
spring事件使用
java·后端·spring
微风粼粼2 小时前
程序员在线接单
java·jvm·后端·python·eclipse·tomcat·dubbo
缘来是庄2 小时前
设计模式之中介者模式
java·设计模式·中介者模式