Solon2 开发深入:容器与动态代理的奥秘

发布时间:2026/10/30 22:34:51
Solon2 开发深入:容器与动态代理的奥秘 在 Java 里动态代理主要分接口动态代理 和 类动态代理。因为它的代理类都是动态创建的所以名字里会带上 “动态”。官网的有些地方叫 “代理”也有些地方叫 “动态代理”。都是一个意思。1、接口动态代理这是 jdk 直接支持的能力。内在的原理是框架会动态生成目标接口的一个代理类即接口的实现类并返回使用者在调用接口的函数时实际上调用的是这个代理类的函数而代理类又把数据转给了调用处理器接口。而整个过程的感受是调用目标接口最终到了 InvocationHandler 的实现类上//1. 定义目标接口 public interface UserService{ void addUser(int userId, String userName); } // //2. 通过JDK接口获得一个代理实例 UserService userService Proxy.getProxy(UserService.class, new InvocationHandlerImpl()); //生成的 UserService 代理类差不多是这个样子 public class UserService$Proxy implements UserService{ final InvocationHandler handler; final Method addUser2; //示意一下别太计较它哪来的 public UserService$Proxy(InvocationHandler handler){ this.handler handler; } Override public void void addUser(int userId, String userName){ handler.invoke(this, addUser2, new Object[](userId, userName)); } } //在调用 userService 时本质是调用 UserService$Proxy 的函数最终又是转发到 InvocationHandler 的实现类上。 // //3. 实现调用处理器接口 public class InvocationHandlerImpl implements InvocationHandler{ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ //... } }mark 一般接口动态代理是为了转发处理。/mark2、类动态代理类的动态代理略麻烦些且要借助字符码工具框架Solon 用的是 ASM。内在的原理倒是相差不大框架会动态生成目标类的一个代理类一个重写了所有函数的子类并返回使用者在调用目标类的函数时实际上调用的是这个代理类的函数而代理类又把数据转给了调用处理器接口。调用处理器在处理时会附加上别的处理。而整个过程的感受是调用目标类可以附加上很多拦截处理//1. 定义目标类 public class UserService{ public void addUser(int userId, String userName){ //.. } } // //2. 通过框架接口获得一个代理实例::注意这里的区别 UserService userService new UserService(); userService AsmProxy.getProxy(UserService.class, new AsmInvocationHandlerImpl(userService)); //生成的 UserService 代理类差不多是这个样子 public class UserService$AsmProxy extends UserService{ final AsmInvocationHandler handler; final Method addUser2; //示意一下别太计较它哪来的 public UserService$Proxy(AsmInvocationHandler handler){ this.handler handler; } Override public void void addUser(int userId, String userName){ handler.invoke(this, addUser2, new Object[](userId, userName)); } } //本质还是调用 UserService$AsmProxy 的函数最终也是转发到 AsmInvocationHandler 的实现类上。 // //3. 实现调用处理器接口 public class AsmInvocationHandlerImpl implements AsmInvocationHandler{ //::注意这里的区别 final Object target; public AsmInvocationHandlerImpl(Object target){ this.target target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ //::注意这里的区别 MethodWrap methodWrap MethodWrap.get(method); //MethodWrap 内部对各种拦截器做了封装处理 methodWrap.invoke(target, args); } }​mark 一般类动态代理是为了拦截并附加处理。/mark3、关于 Solon 的类代理情况与 “函数环绕拦截”对 Solon 来讲只有一个函数反射后再经 MethodWrap 执行的就是被代理了。所有的 “函数环绕拦截” 处理就封装在 MethodWrap 里面。Controller、Remoting 注解的类这两个注解类没有 ASM 的类代码但是它们的 Method 会转为 MethodWrap 并包装成 Action 注册到路由器。即它们是经 MethodWrap 再调用的。所以它们有代理能力支持 “函数环绕拦截”。Service、Dao、Repository 注解的类这三个注解来自 solon.aspect 插件包它们注解的类都会被 ASM 代理。跟上面原理分析的一样也支持 “函数环绕拦截”。有克制的拦截Solon 不支持表达式的随意拦截必须以注解为 “切点” 进行显示拦截。mark 所以 Solon 不用为所有的 Bean 增加代理能力按需添加即可 /mark。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询