【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会根据情况自动选择最合适的代理方式。

相关推荐
冬天vs不冷2 分钟前
Java基础(九):Object核心类深度剖析
java·开发语言·python
TS的美梦3 分钟前
【1:1复刻R版】python版火山图函数一键出图
开发语言·python·r语言·scanpy·火山图
CF14年老兵15 分钟前
Python万物皆对象:从懵懂到顿悟的奇妙之旅
后端·python·trae
这里有鱼汤18 分钟前
发现个用《道德经》+价值投资大咖的智慧,做A股的AI诊股神器,居然还开源了
python
悟空聊架构22 分钟前
我的网站被攻击了,被干掉了 120G 流量,还在持续攻击中...
java·前端·架构
鸢栀w43 分钟前
前端css学习笔记7:各种居中布局&空白问题
前端·css·笔记·学习·尚硅谷网课
陈天伟教授1 小时前
(二)Python + 地球信息科学与技术 (GeoICT)=?
开发语言·python
Dajiaonew1 小时前
Spring AI RAG 检索增强 应用
java·人工智能·spring·ai·langchain
Hero_11271 小时前
学习Stm32 的第一天
stm32·嵌入式硬件·学习
之歆1 小时前
大模型微调分布式训练-大模型压缩训练(知识蒸馏)-大模型推理部署(分布式推理与量化部署)-大模型评估测试(OpenCompass)
人工智能·笔记·python