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

相关推荐
重整旗鼓~4 分钟前
2.微服务-配置
java·spring·微服务
zeijiershuai13 分钟前
Mybatis-入门程序、 数据库连接池、XML映射配置文件、MybatisX
xml·java·开发语言·mybatis
覆东流20 分钟前
Python语法特点与编码规范
python
java122426 分钟前
== 和 equals 的区别
java
是三好26 分钟前
Lock锁
java·juc
小手WA凉27 分钟前
Gradle快速入门
java·spring·gradle
Bonnie_12151 小时前
04-jenkins学习之旅-java后端项目部署实践
学习
搞不懂语言的程序员1 小时前
Elasticsearch简单集成java框架方式。
java·大数据·elasticsearch
每次的天空1 小时前
Android计算机网络学习总结
学习·计算机网络
与己斗其乐无穷1 小时前
数据结构(5)线性表-栈
数据结构·学习