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技之暗送秋波的技术的更多相关文章

  1. 【Java技术系列】爱情36技之追美妹的技术

    1. 在古老的非洲大陆上,有个原始人无意中抬头仰望星空,凝视的时间稍微长了一些,超过了外星人设置的阈值,立刻拉响了人类即将产生文明的警报.因为外星人认为,人类已经产生了对宇宙的好奇心,文明的产生,科技 ...

  2. 【Java技术系列】爱情36技之记忆永存

    1.  关注“一猿小讲”的伙伴们都清楚,Java 那小子带着心爱的 Python 菇凉,去了一趟浪漫的土耳其,然后一起又去了东京和巴黎,接着 Python 菇凉自己又去了云南的大理. 就在昨天,Pyt ...

  3. 【Java技术系列】爱情36技之Bug大战

    1. 鲁迅先生说:程序员,天不怕地不怕,就怕小虫儿爬呀爬,爬呀爬. 随着时间的推移,鲁迅先生又说:真正勇猛的程序员,敢于让虫子面对惨淡的虫生. 虫子在程序员心中是啥东西?虫子的学名为 Bug,是多少入 ...

  4. java秒杀系列(2)- 页面静态化技术

    前言 通过代码片段分别介绍服务端渲染.客户端渲染.对象缓存三种方式的写法. 代码片段仅供参考,具体实现需要根据业务场景自行适配,但思想都是一样. 一.服务端渲染方式 1.接口返回html页面的设置 @ ...

  5. Java基础系列(36)- 数组三种初始化及内存分析

    内存分析 数组三种初始化 静态初始化 int[] a = {1,2,3}; Man[] mans = {new Man(1,1),new Man(2,2)} 动态初始化 int[] a = new i ...

  6. 【OCR技术系列之五】自然场景文本检测技术综述(CTPN, SegLink, EAST)

    文字识别分为两个具体步骤:文字的检测和文字的识别,两者缺一不可,尤其是文字检测,是识别的前提条件,若文字都找不到,那何谈文字识别.今天我们首先来谈一下当今流行的文字检测技术有哪些. 文本检测不是一件简 ...

  7. Docker 技术系列之安装Docker Desktop for Mac

    终于要进入到Docker技术系列了,感谢大家的持续关注. 为什么要选择Docker?因为Docker 轻巧快速,提供了可行.经济.高效的替代方案.举个例子,安装Nginx,Mysql,Redis等常用 ...

  8. 1.Java 加解密技术系列之 BASE64

    Java 加解密技术系列之 BASE64 序号 背景 正文 总结 序 这段时间,工作中 用到了 Java 的加解密技术,本着学习的态度,打算从这篇文章开始,详细的研究一番 Java 在加解密技术上有什 ...

  9. Java 加解密技术系列文章

    Java 加解密技术系列之 总结 Java 加解密技术系列之 DH Java 加解密技术系列之 RSA Java 加解密技术系列之 PBE Java 加解密技术系列之 AES Java 加解密技术系列 ...

随机推荐

  1. 安装ArchLinux时遇到的部分问题

    目录 一.网络问题 1.安装刚开始时连接wifi 2.安装完桌面后 二.卸载gnome桌面 三.启动桌面(以kde桌面为例) 1.立即启动桌面(start , stop) 2.设置开启自启动 (ena ...

  2. 【05】openlayers 网格图层

    效果: 创建地图: //创建地图 var map = new ol.Map({ //设置显示地图的视图 view: new ol.View({ projection: 'EPSG:4326', //投 ...

  3. 有了这套微信小程序x5调试,调试一些简单的开发者工具调试不了的功能不成问题!!!!

    1.首先我们需要打开微信 TBS 调试 地址是:http://debugx5.qq.com 2.然后打开手机 打开开发者模式,打开 USB 调试 3.然后 在谷歌浏览器地址栏输入 chrome://i ...

  4. html标签及网页语义化理解

    最近重新看了一遍html标签的知识,有很多新的体会,对语义化有了一个新的理解. 那么什么叫做语义化呢,说的通俗点就是:明白每个标签的用途(在什么情况下使用此标签合理)比如,网页上的文章的标题就可以用标 ...

  5. Echart饼形图和折线图的循环展示及选择展示

    需求:根据不同的入参调同一接口,循环展示一组饼形图或折线图: 主要问题:在于给定的数据格式不符合图表的配置项格式,需要拆分组装数据:首先默认展示几个图表,当选中一个类别,需要展示其中一个的时候,页面中 ...

  6. python_字符串&列表&元组&字典之间转换学习

    #!/usr/bin/env/python #-*-coding:utf-8-*- #Author:LingChongShi #查看源码Ctrl+左键 #数据类型之间的转换 Str='www.baid ...

  7. CSS样式命名

    CSS样式命名    说明网页公共命名#wrapper    页面外围控制整体布局宽度#container或#content    容器,用于最外层#layout    布局#head, #heade ...

  8. 《Linux环境进程间通信》系列文章链接

    深刻理解 Linux 进程间通信(IPC) http://www.ibm.com/developerworks/cn/linux/l-ipc/index.html Linux 环境进程间通信(一): ...

  9. 是时候了解Java Socket底层实现了

    在Java中,提供了一系列Socket API,可以轻松建立两个主机之间的连接.读取数据,那底层到底怎么实现,很少人去关心.这其实最终还是通过调用操作系统提供得Socket接口完成(TCP/IP是由操 ...

  10. Journal of Proteome Research | Improving Silkworm Genome Annotation Using a Proteogenomics Approach (分享人:张霞)

    题目:Improving Silkworm Genome Annotation Using a Proteogenomics Approach 期刊:Journal of Proteome Resea ...