【Java技术系列】爱情36技之暗送秋波的技术
1.
这篇文章想分享已经很久了,苦于皱巴巴的技术比较生涩难懂,迟迟没有找到好的分享方式,今天结合爱情中暗送秋波的故事的形式,尝试分享一下。
以后如果再有人问你们:能否在加载类的时候,对字节码进行修改?如何实现零侵入、松耦合的方式,采集 Java 程序的各种运行信息?等等一系列的问题时,请不要再懵圈摇头,尝试结合下面分享的爱情故事,回答一下也未尝不可。
准备好小板凳,爱情故事要开始啦。
2.
自从 Java 那小子靠《爱情36技之追美妹的技术》喜获 Python 菇凉的芳心后,就开始与 Python 菇凉一起进行着各种浪漫的旅行。
Java 先带着心爱的 Python 菇凉去了一趟浪漫的土耳其,然后一起又去了东京和巴黎,其实 Java 特别喜欢迈阿密,和有黑人的洛杉矶,但是 Python 菇凉还是比较想去云南的大理,在云南大理的天涯海角来个海枯石烂、海誓山盟,这样保留着回忆才更有意义。于是让 Java 那小子订了两张 9012 年 7 月 4 日的飞往云南大理的机票。
往往计划赶不上变化,Java 那小子所在的公司要组织晋升培训,为了能让 Python 菇凉以后的生活更惬意,Java 那小子决定不去云南大理了,但是还想让 Python 菇凉独自去欣赏一下大理的美景。
Java 那小子还实在放心不下 Python 菇凉,担心她坐飞机是否安全?担心她独自一人是否会难过?
有没有一种方式能够实时关注到她的动态呢?只有知道 Python 菇凉的动态,Java 那小子才能安心工作,才能时不时的送去爱意的秋波。
好奇、郁闷、纠结的 Java,遂拿起压箱底的《爱情36技》捣腾了好一会儿,忽然捣腾第 34 技——暗送秋波的技术,Java 眼前一亮,心中乐开了花。
Java 那小子结合自身需求,认真展开了对《爱情 36 技》中的暗送秋波攻略使用解读。
暗送秋波的技术攻略,谨献给那些:想实时关心对方的动态,时不时还想再来个嘘寒问暖的小哥哥小姐姐们。不过此良策说的好听一点是关心对方,说的不好听一点那就是监控对方(捂嘴笑)。
首先声明此良策,需要为对方亲手打造一款随身携带的设备,需要耗费人力财力... ...
认真读完攻略,Java 下意识的认为,需要先给将要打造的随身携带的设备起个名字,以彰显自己的才能,并能让 Python 菇凉欣然接受这个设备。
Java 灵光乍现,由于设备出自我之手,肯定名字也要随着我的姓,不妨就取个卡哇伊的中文名字为:Java 的随身听,英文名字:JavaWalkmanAgent,学名为:javaagent。
考虑到 Python 菇凉远行,不能携带太重的行李。于是 Java 按照书中的步骤,绞尽脑汁,一步一步的开始为 Python 菇凉打造这款便捷小巧的随身听设备。
第一步:确定要把秋天的菠菜送给谁
Java 准备把亲身打造的随身听设备,送给 Python 菇凉。其中 Python 菇凉去大理会经历两件事,一件事是坐飞机去大理,另一件是去天涯海角来一场浪漫的海誓山盟。
package com.love36.ogle; public class PythonGirl { public static void goByPlane() {
System.out.println("Python 菇凉说==> 我心爱的Java没有一起坐飞机,心中还是有点失落");
} public static void sayLoveOath() {
System.out.println("Python 菇凉说==> Java没来大理有遗憾,但是海可枯石可烂,我对他的爱情永不变");
} public static void main(String[] args) {
System.out.println("随身听 设备说==> 我是 Java 制作的随身听设备,专门替 Java 照顾 Python 菇凉,并默默暗送秋波");
// 1. 坐飞机去大理浪漫
goByPlane();
// 2. 一个人的山盟海誓
sayLoveOath();
}
}
第二步:用心打造暗送秋波设备的骨架
在 Python 菇凉做每件事之前,JavaWalkmanAgent 都会第一时间拦截到。
第三步:伺机而动。
Java 提前种植好情意绵绵、嘘寒问暖的菠菜,然后在 Python 菇凉做每件事之前或者之后默默送过去。
package com.love36.ogle; import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod; import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain; public class JavaWalkmanAgent { public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("随身听 设备说==> 我是 Java 制作的随身听设备,专门替 Java 照顾 Python 菇凉,并默默暗送秋波");
// 随身听开始发挥自己的作用吧
inst.addTransformer(new ClassFileTransformer() {
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
byte[] transformed = null;
CtClass cl = null;
try {
ClassPool pool = ClassPool.getDefault();
cl = pool.makeClass(new java.io.ByteArrayInputStream(classfileBuffer));
if (!cl.isInterface()) {
CtMethod[] methods = cl.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
CtMethod method = methods[i];
//随身听发现 Python 菇凉正在坐飞机,提醒系好安全带
if ("com.love36.ogle.PythonGirl.goByPlane()".equals(method.getLongName())) {
//在 Python 菇凉坐飞机之前问候一下
method.insertBefore("System.out.println(\"Java 那小子说==> 心爱的Python,飞机要起飞了,请系好安全带,一路平安。\");");
//在 Python 菇凉坐飞机之后慰问一下
method.insertAfter("System.out.println(\"Java 那小子说==> 心爱的Python,安全抵达大理,愿玩的开心。\");");
} //随身听发现 Python 菇凉正在海誓山盟,Java远程寄相思
if ("com.love36.ogle.PythonGirl.sayLoveOath()".equals(method.getLongName())) {
//在 Python 菇凉海誓山盟之后再补充一下
method.insertAfter("System.out.println(\"Java 那小子说==> 我心爱的Python," +
"虽然未能一起去大理的天涯海角浪漫,但是我的心却始终在你身边,注意回来的时候买点土特产(捂嘴笑)。\");");
}
}
transformed = cl.toBytecode();
}
} catch (Exception e) {
System.err.println("随身听 设备说==> 我只照顾像Python这样的姑娘,老爷们就不要硬往上凑了。");
} finally {
if (cl != null) {
cl.detach();
}
}
return transformed;
}
});
}
}
第四步:为暗送秋波的随身听设备提供配置手册。
Manifest-Version: 1.0
Premain-Class: com.love36.ogle.JavaWalkmanAgent
Boot-Class-Path: /app/love36/lib/javassist-3.16.1-GA.jar
至此,暗送秋波的随身听设备在 Java 那小子用心打造下完成了,只见 Java 那小子轻轻松松的在开发工具上把上面做的一切合成到一起,导出了 walkman.jar。
Java 已经忍不住想一键启动,暗送秋波的随身听设备,看看有没有达到预期的效果。于是 Java 在心中默默输入如下命令。
java -javaagent:walkman.jar com.love36.ogle.PythonGirl
结果确实让 Java 那小子很惊喜,因为在没有打扰 Python 菇凉的行程下,Java 那小子也完成了对 Python 菇凉的暗送秋波,嘘寒问暖。
锻炼视力的时候到了,睁大眼睛看效果。
视力不好,那我们再放大一点看,居然 Java 那小子无时无刻不在关心着 Python 姑娘,确实挺神奇。
3.
故事讲完了,暗送秋波的攻略你 get 到了没?容我们用技术的行话再来总结一下。
暗送秋波是指:通过 javaagent 植入代码的方式,松耦合的完成目标对象的字节码修改。
经常使用场景:在方法体前后加入统计方法耗时的代码段;统计 SQL 耗时;最重要的是实现调用链路跟踪;许多 APM 开源轮子,比如 Pinpoint、SkyWalking 等,就是使用这项技术对代码进行的增强。
题外话:其实我在面试别人的时候,偶尔也会谈到这个知识点,因为可以考察一下求职者有没有相关解决思路以及技术的深度。
好了,今天的故事就讲完了,希望对你们有帮助。
【Java技术系列】爱情36技之暗送秋波的技术的更多相关文章
- 【Java技术系列】爱情36技之追美妹的技术
1. 在古老的非洲大陆上,有个原始人无意中抬头仰望星空,凝视的时间稍微长了一些,超过了外星人设置的阈值,立刻拉响了人类即将产生文明的警报.因为外星人认为,人类已经产生了对宇宙的好奇心,文明的产生,科技 ...
- 【Java技术系列】爱情36技之记忆永存
1. 关注“一猿小讲”的伙伴们都清楚,Java 那小子带着心爱的 Python 菇凉,去了一趟浪漫的土耳其,然后一起又去了东京和巴黎,接着 Python 菇凉自己又去了云南的大理. 就在昨天,Pyt ...
- 【Java技术系列】爱情36技之Bug大战
1. 鲁迅先生说:程序员,天不怕地不怕,就怕小虫儿爬呀爬,爬呀爬. 随着时间的推移,鲁迅先生又说:真正勇猛的程序员,敢于让虫子面对惨淡的虫生. 虫子在程序员心中是啥东西?虫子的学名为 Bug,是多少入 ...
- java秒杀系列(2)- 页面静态化技术
前言 通过代码片段分别介绍服务端渲染.客户端渲染.对象缓存三种方式的写法. 代码片段仅供参考,具体实现需要根据业务场景自行适配,但思想都是一样. 一.服务端渲染方式 1.接口返回html页面的设置 @ ...
- Java基础系列(36)- 数组三种初始化及内存分析
内存分析 数组三种初始化 静态初始化 int[] a = {1,2,3}; Man[] mans = {new Man(1,1),new Man(2,2)} 动态初始化 int[] a = new i ...
- 【OCR技术系列之五】自然场景文本检测技术综述(CTPN, SegLink, EAST)
文字识别分为两个具体步骤:文字的检测和文字的识别,两者缺一不可,尤其是文字检测,是识别的前提条件,若文字都找不到,那何谈文字识别.今天我们首先来谈一下当今流行的文字检测技术有哪些. 文本检测不是一件简 ...
- Docker 技术系列之安装Docker Desktop for Mac
终于要进入到Docker技术系列了,感谢大家的持续关注. 为什么要选择Docker?因为Docker 轻巧快速,提供了可行.经济.高效的替代方案.举个例子,安装Nginx,Mysql,Redis等常用 ...
- 1.Java 加解密技术系列之 BASE64
Java 加解密技术系列之 BASE64 序号 背景 正文 总结 序 这段时间,工作中 用到了 Java 的加解密技术,本着学习的态度,打算从这篇文章开始,详细的研究一番 Java 在加解密技术上有什 ...
- Java 加解密技术系列文章
Java 加解密技术系列之 总结 Java 加解密技术系列之 DH Java 加解密技术系列之 RSA Java 加解密技术系列之 PBE Java 加解密技术系列之 AES Java 加解密技术系列 ...
随机推荐
- JetBrains 第二轮:再为免费全家桶续命三个月
昨天分享了如何通过参与JetBrains的解密任务来获取正版全家桶的兑换码.今天 JetBrains 一早继续在Twitter推出第二波任务: 下面,我们就继续来一起参与一下,为我们的正版JetBra ...
- DBProxy快速入门
1. DBProxy安装 1.1 安装依赖项 CentOS yum install -y Percona-Server-devel-55.x86_64 Percona-Server-client-55 ...
- 大龄IT人的新的一年
一转眼,工作十几年了,之前由于有时要出差,孩子偶尔放回老家,有时到处找人看孩子,虽然不出差时都是有我来带,孩子还是和我很亲,但是一直没时间关注她的学习,只是睡前读读绘本,报了个英语培训班,偶尔玩玩识字 ...
- react 脚手架装后 运行eject报错 的 正确运行方式
git init git add . git commit -m 'init' npm run eject 或者 cnpm run eject
- Git 基础入门
目录 git安装 基本设置 创建版本库 相关概念 将代码提交到分支仓库 版本回退 代码修改 撤销修改 文件删除 github 远程仓库 添加远程仓库 克隆远程仓库 分支操作 忽略特殊文件 git安装 ...
- Java多线程详解(转载)
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用 ...
- Natas29 Writeup(Perl命令注入、00截断、绕过过滤)
Natas29: 本关打开后,可以看到一个下拉列表,选择不同的内容,会得到不同的大量文本的页面. 观察url部分:http://natas29.natas.labs.overthewire.org/i ...
- scrapy框架在未登录模式下爬取文本,文件和图片的几点收获
1.什么是API接口? https://baijiahao.baidu.com/s?id=1597881116201407882&wfr=spider&for=pc 2.spider文 ...
- Red Team 工具集之网络钓鱼和水坑攻击
来自:信安之路(微信号:xazlsec),作者:myh0st 参考项目:https://github.com/infosecn1nja/Red-Teaming-Toolkit 上图是一个 Red Te ...
- greenplum数据库常用操作
1. 场景描述 greenplum集群部署好后,软件老王在实际使用过程中碰到一些问题,简单记录下,希望能帮到有需要的朋友. 2 .解决方案 2.1 gpcc监控地址 说明:非常重要,greenplum ...