温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java Proxy 代理原理是什么

发布时间:2026-10-09 15:14:19 来源:亿速云 阅读:96 作者:小樊 栏目:编程语言

在 Java 中,**Proxy(代理)**通常分为两类:

  1. 静态代理
  2. 动态代理(JDK 动态代理 + CGLIB 等)

下面从「原理」角度系统说明。


一、什么是代理(Proxy)

代理模式:为某个对象提供一个代理对象,由代理对象控制对真实对象的访问。

核心目的:

  • 在不修改原类代码的情况下增强功能(日志、事务、权限、监控等)
  • 解耦调用方与目标对象

二、静态代理原理

原理

在编译期就手动编写代理类,代理类实现和目标类相同的接口,并持有目标对象引用。

示例

interface UserService {
    void save();
}

class UserServiceImpl implements UserService {
    public void save() {
        System.out.println("保存用户");
    }
}

class UserServiceProxy implements UserService {
    private UserService target;

    public UserServiceProxy(UserService target) {
        this.target = target;
    }

    public void save() {
        System.out.println("前置增强");
        target.save();
        System.out.println("后置增强");
    }
}

特点

  • 编译期确定
  • 简单直观
  • 缺点:类多、维护成本高

三、JDK 动态代理原理(重点)

1. 核心类

  • java.lang.reflect.Proxy
  • java.lang.reflect.InvocationHandler

2. 原理流程

运行期动态生成代理类(字节码)

步骤:

  1. 定义接口
  2. 实现 InvocationHandler
  3. 使用 Proxy.newProxyInstance() 创建代理对象
  4. JVM 在内存中动态生成代理类(实现指定接口)
  5. 方法调用 → 转发到 InvocationHandler.invoke()

3. 示例

UserService proxy = (UserService) Proxy.newProxyInstance(
    UserService.class.getClassLoader(),
    new Class[]{UserService.class},
    (obj, method, args) -> {
        System.out.println("前置");
        Object result = method.invoke(target, args);
        System.out.println("后置");
        return result;
    }
);

4. 底层原理

  • 动态生成的代理类:
    • 继承 Proxy
    • 实现指定接口
    • 方法调用委托给 InvocationHandler
  • 生成方式:
    • JDK 使用 sun.misc.ProxyGenerator 生成字节码
    • 类加载器加载到 JVM

5. 限制

✅ 只能代理 接口 ❌ 不能代理类(无接口的类不行)


四、CGLIB 动态代理原理

1. 原理

  • 通过继承目标类生成子类
  • 重写父类方法
  • 使用字节码技术(ASM)

2. 示例

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
    System.out.println("前置");
    Object result = proxy.invokeSuper(obj, args);
    System.out.println("后置");
    return result;
});
UserService proxy = (UserService) enhancer.create();

3. 特点

✅ 可代理类
✅ 不需要接口
❌ 不能代理 final 类 / final 方法


五、JDK vs CGLIB 对比

对比项 JDK 动态代理 CGLIB
实现方式 接口 继承
性能 调用稍慢 生成慢,调用快
限制 必须有接口 不能 final
使用场景 Spring 接口 Bean Spring 类 Bean

六、Spring AOP 中的代理

  • 有接口 → JDK 动态代理
  • 无接口 → CGLIB
  • @EnableAspectJAutoProxy(proxyTargetClass = true) 强制 CGLIB

七、一句话总结

Java Proxy 的本质是:在运行期生成代理类,将方法调用拦截并转发到统一的处理逻辑,从而实现功能增强。

如果你愿意,我也可以:

  • 画一张代理调用流程图
  • 讲 Spring AOP 源码级原理
  • 对比 MyBatis / RPC 中的代理应用
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手