温馨提示×

温馨提示×

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

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

java Proxy代理最佳实践

发布时间:2026-10-31 08:40:18 来源:亿速云 阅读:95 作者:小樊 栏目:编程语言

在 Java 中,**Proxy(代理)**通常指两种常见场景:

  1. JDK 动态代理(java.lang.reflect.Proxy)
  2. CGLIB / ByteBuddy 等字节码代理(Spring AOP 常用)

下面从使用方式、最佳实践、常见坑三个角度系统说明。


一、JDK 动态代理最佳实践

1. 基本使用

public interface UserService {
    void save();
}

public class UserServiceImpl implements UserService {
    public void save() {
        System.out.println("save user");
    }
}

public class LogProxy implements InvocationHandler {
    private Object target;

    public LogProxy(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before");
        Object result = method.invoke(target, args);
        System.out.println("after");
        return result;
    }
}

// 使用
UserService proxy = (UserService) Proxy.newProxyInstance(
        target.getClass().getClassLoader(),
        target.getClass().getInterfaces(),
        new LogProxy(target)
);

2. 最佳实践

✅ 只代理接口,不代理类(JDK Proxy 限制)
✅ InvocationHandler 保持无状态或线程安全
✅ 避免 Proxy 对象被序列化(除非必要)
✅ 不要在 invoke 中再调用 proxy 方法,避免递归

// 错误示例(递归)
public Object invoke(...) {
    return method.invoke(proxy, args); // ❌
}

✅ 统一异常处理

try {
    return method.invoke(target, args);
} catch (InvocationTargetException e) {
    throw e.getTargetException();
}

二、Spring AOP / CGLIB 代理最佳实践

1. Spring 中的两种代理

场景 代理方式
有接口 JDK 动态代理
无接口 CGLIB
@EnableAspectJAutoProxy(proxyTargetClass = true) // 强制 CGLIB

2. 最佳实践

✅ 方法必须是 public(CGLIB 也推荐)
✅ 避免同类方法内部调用(AOP 失效)

public void a() {
    b(); // ❌ AOP 不生效
}

@Transactional
public void b() {}

✅ 使用接口而非具体类作为注入类型

@Autowired
UserService userService; // ✅

✅ 事务 / 日志 / 权限统一用 AOP,不要手写 Proxy


三、RPC / 远程调用中的 Proxy 实践

典型应用:Feign、MyBatis Mapper、Dubbo

UserService userService = Proxy.newProxyInstance(
    classLoader,
    new Class[]{UserService.class},
    (proxy, method, args) -> rpcInvoke(method, args)
);

✅ 接口只定义契约,不写实现
✅ Proxy 负责网络 / 序列化细节
✅ 方法签名稳定,避免重载


四、性能与选型建议

场景 推荐
简单日志 / 鉴权 JDK Proxy
Spring 项目 Spring AOP
高性能字节码 ByteBuddy
Android 不推荐动态代理

⚠️ 动态代理有性能开销,不要在热点循环中创建 Proxy


五、常见坑总结

❌ Proxy 对象 instanceof 实现类 为 false
❌ 私有方法无法被代理
❌ final 类 / final 方法无法 CGLIB
❌ 代理链过深导致调试困难


六、一句话总结

Java Proxy 的最佳实践:用接口定义行为,用代理处理横切逻辑,避免滥用,优先使用成熟框架(Spring AOP / ByteBuddy)。

如果你有具体使用场景(Spring / RPC / 测试 Mock),我可以给更针对性的示例。

向AI问一下细节

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

AI
助
手