能,但需通过 proxy.getinvocationhandler(proxy) 获取 handler 后,再调用其 gettargetsource().gettarget() 安全提取目标对象;直接反射访问 h 字段在 jdk 16+ 和 spring 6.1+ 中已被禁止。

不能直接从 JDK 动态代理对象里“取出”原对象,因为代理本身不持有目标实例的公开引用;但可以通过调用处理器(InvocationHandler)间接获取——前提是 handler 内部确实封装了 target,且你有访问权限。
确认是标准 JDK 代理对象
Spring 默认在有接口时用 JDK 代理,无接口时用 CGLIB;只有前者才适用 Proxy.getInvocationHandler()。先做类型校验:
- 用
proxy instanceof Proxy判断运行时是否为 JDK 代理实例 - 或更严谨地:
Proxy.isProxyClass(proxy.getClass()) - 若返回
false(比如 CGLIB 代理、手工写的静态代理),此路不通,需换策略
安全获取 InvocationHandler
这是唯一官方支持、跨 JDK 版本稳定的入口:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 调用
Proxy.getInvocationHandler(proxy)得到 handler 实例 - 该方法在非法参数下抛
IllegalArgumentException,务必 try-catch - 注意:它返回的是 handler,不是原对象——只是通往原对象的“钥匙”
从 handler 中提取 target(依赖具体实现)
handler 是个接口,实际类由你或框架提供。常见情况:
- 你自己写的
InvocationHandler:如果字段private Object target是 public 或可反射访问,且未被模块化限制(JDK 9+),可用Field.setAccessible(true)读取(但 JDK 16+ 默认禁止,需加启动参数或改用其他方式) - Spring 的
JdkDynamicAopProxy:target 封装在Advised对象里,而Advised又藏在 handler 内部;Spring 6.1+ 将关键字段设为final和包私有,**不再推荐也不支持反射提取** - 真正可靠的做法:如果使用 Spring,应通过
Advised接口提供的getTargetSource().getTarget()——这是 Spring 官方支持的获取途径,需确保 handler 实现了Advised(如JdkDynamicAopProxy就实现了)
替代思路:避免提取,改用设计解耦
频繁需要原对象,往往说明架构存在隐患:
- 尽量让业务逻辑面向接口编程,不依赖具体实现类
- 若必须操作原对象(如序列化、深拷贝、调试),考虑在创建代理前保留对原始 bean 的引用
- Spring 环境下,可通过
ApplicationContext.getBean("beanName", Class)直接获取未代理的原始 bean(需关闭对应 bean 的 AOP 或使用@Primary+ 条件装配等技巧)










