先贴上思路的整体流程:
文章插图
首先新建Maven工程 , 在Maven依赖中引用JVM SandBox , 官方推荐独立工程使用parent方式 。
<parent><groupId>com.alibaba.jvm.sandbox</groupId><artifactId>sandbox-module-starter</artifactId><version>1.2.0</version></parent>
新建一个类作为一个JVM SandBox模块 , 如下图:文章插图
使用@Infomation声明mode为AGENT模式 , 一共有两种模式Agent和Attach 。
- Agent:随着JVM启动一起启动
- Attach:在已经运行的JVM进程中 , 动态的插入
其次 , 继承com.alibaba.jvm.sandbox.api.Module和com.alibaba.jvm.sandbox.api.ModuleLifecycle 。
其中ModuleLifecycle包含了整个模块的生命周期回调函数 。
- onLoad:模块加载 , 模块开始加载之前调用!模块加载是模块生命周期的开始 , 在模块生命中期中有且只会调用一次 。这里抛出异常将会是阻止模块被加载的唯一方式 , 如果模块判定加载失败 , 将会释放掉所有预申请的资源 , 模块也不会被沙箱所感知
- onUnload:模块卸载 , 模块开始卸载之前调用!模块卸载是模块生命周期的结束 , 在模块生命中期中有且只会调用一次 。这里抛出异常将会是阻止模块被卸载的唯一方式 , 如果模块判定卸载失败 , 将不会造成任何资源的提前关闭与释放 , 模块将能继续正常工作
- onActive:模块被激活后 , 模块所增强的类将会被激活 , 所有com.alibaba.jvm.sandbox.api.listener.EventListener将开始收到对应的事件
- onFrozen:模块被冻结后 , 模块所持有的所有com.alibaba.jvm.sandbox.api.listener.EventListener将被静默 , 无法收到对应的事件 。需要注意的是 , 模块冻结后虽然不再收到相关事件 , 但沙箱给对应类织入的增强代码仍然还在 。
- loadCompleted:模块加载完成 , 模块完成加载后调用!模块完成加载是在模块完成所有资源加载、分配之后的回调 , 在模块生命中期中有且只会调用一次 。这里抛出异常不会影响模块被加载成功的结果 。模块加载完成之后 , 所有的基于模块的操作都可以在这个回调中进行
而SpringBeanStartMonitor的核心代码如下图:
文章插图
使用Sandbox的doClassFilter过滤出匹配的类 , 这里我们是BeanFactory 。
使用doMethodFilter过滤出要监听的方法 , 这里是initializeBean 。
里取initializeBean作为统计耗时的切入方法 。具体为什么选择该方法 , 涉及到SpringBean的启动生命周期 , 不在本文赘述范围内 。(本文作者:蛮三刀酱)
文章插图
接着使用
moduleEventWatcher.watch(springBeanFilter, springBeanInitListener, Event.Type.BEFORE, Event.Type.RETURN);
将我们的springBeanInitListener监听器绑定到被观测的方法上 。这样每次initializeBean被调用 , 都会走到我们的监听器逻辑 。
监听器的主要逻辑如下:
经验总结扩展阅读
- 如何理解Java中眼花缭乱的各种并发锁?
- 鳝鱼怎么杀和洗
- 紫河车粉的最佳吃法
- 2023年属龙人农历十月婚嫁如何 哪天结婚吉祥
- 新qq如何快速升级qq怎么快速升级(在qq怎么快速升级等级)
- 英雄联盟怎么玩好(新人如何玩好英雄联盟)
- 如何才能玩好英雄联盟(怎么样才能玩英雄联盟最好)
- 手把手教你使用netty搭建一个DNS tcp服务器
- 2023测绘类专业包括哪些 就业前景如何
- 什么是 X.509 证书以及它是如何工作的?