千家信息网

不用Jar包的Agent的优点有哪些

发表于:2024-11-11 作者:千家信息网编辑
千家信息网最后更新 2024年11月11日,本篇内容介绍了"不用Jar包的Agent的优点有哪些"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!提
千家信息网最后更新 2024年11月11日不用Jar包的Agent的优点有哪些

本篇内容介绍了"不用Jar包的Agent的优点有哪些"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

提起 JavaAgent,很多人都说几句,就像古龙武侠小说里的「孔雀翎」,威力很大,江湖上都是它的传说。但真的见识过的人并没几个。

JavaAgent 虽说没这么神秘,但也一直给人曲高和寡的感觉,除了一些中间件产品、大型的框架中使用外,在业务中一直很少出现。

原因可能有很多,一来是可能确实不需要,再者需要开发独立的 Agent Jar 文件,在 Jar 内对类的 transform 开发也并不容易。

我们知道,无论是启动时的 Java Agent,还是运行时的动态 attach 到远程JVM, 都是为了拿到 Instrument,对 class 的字节码进行修改。这么底层的东西,当然使用起来让人不太容易下手。

不过就像机器语言不方便,人们发明了汇编语言,又发现了高级语言。对于字节码的操作也类似,人们觉得直接操作字节码有难度,而且需要深入理解 JVM 规范,具体什么位置多少字节代表啥,这不是一般人喜欢的,于是 ASM 框架出现了;但还是有规范的影子,不太「高级」,于是又出现了Javassist 这一类的「高级」工具。

我们今天要说的这个工具,和 Javassist 类似,都提供了更高层的API,来操作class,对普通程序员更友好,除此之外呢?

就像今天人们购物、读书等,都更相信专业的平台、或者专家的推荐,像XX严选,XX读书会推荐。今天说的这个工具是Duke 的推荐,对,就是它, Java 的吉祥物,这个小胖子。今天的这个工具在 2015年被 Oracle 评选为「Duke's Choice award」。

除了Duke,框架也得到了众多开发者的认可,每年有七千多万次的下载。

这个工具是:Bytebuddy。

从名字你就看的出来,它立志要做字节码的好伙伴。所以在很多开源框架里也能看到它的身影。

既然已经有了不少的工具, byteBuddy能带来什么不一样呢?

除了API 上的简洁易操作,官方自己也大字强调了运行时动态的「代码生成和字节码操作」,不需要再借助 Java 编译器。

来看看官网是怎么自我介绍的,后面再附上几个代码片段,就能很快 Get 到了。

官网:https://bytebuddy.net/

Byte Buddy is a code generation and manipulation library for creating and modifying Java classes during the runtime of a Java application and without the help of a compiler. Other than the code generation utilities that ship with the Java Class Library, Byte Buddy allows the creation of arbitrary classes and is not limited to implementing interfaces for the creation of runtime proxies. Furthermore, Byte Buddy offers a convenient API for changing classes either manually, using a Java agent or during a build.

阅读理解开始。重点你一定会看到了:

  • 「code generation」

  • 「creating and modifying Java classes」

作者贴心的加了一段小字来描述框架的优势。选重点的说就是:

  1. 鸿蒙官方战略合作共建--HarmonyOS技术社区

  2. 不需要理解字节码,也不需要理解class 文件格式

  3. API 非侵入,设计简洁易懂

  4. 高度可定制,可以任意自定义

我自己认为该把这点也加上,不写 Java Agent 也可以 Attach 到 JVM 上,把 ByteBuddy 自己当成一个Agent,运行时直接install。Cool。

不写JVM Agent 也能对类拦截和修改,我们来认识下揭开字节码修改黑魔法的家伙。

为了对 Class 进行一些操作,我们一般都离不了 JVM Agent。不管是启动时直接连接,还是运行时动态的 Attach到对应的JVM 上,都需要 Agent。也就是我们熟悉的premain 和 agentmain 的触发入口,通过它们,我们才能拿到 Instrumentation,从而进行 transform和 redeine。

但这个东西的使用,给人总是「阳春白雪」的感觉,让人觉得是黑魔法一样,一般不会轻易尝试使用。

有了ByteBuddy,就不用再羡慕一些框架的「运行时增强」,「动态织入」等等,都可以实现。

如何上手呢?

只需要下载 Jar 文件或者 Maven 添加依赖之后就能狂奔了。

比如官方的这个 HelloWorld

Class dynamicType = new ByteBuddy()   .subclass(Object.class)   .method(ElementMatchers.named("toString"))   .intercept(FixedValue.value("Hello World!"))   .make()   .load(getClass().getClassLoader())   .getLoaded();   assertThat(dynamicType.newInstance().toString(), is("Hello World!"));

直接把 Object 的 toString 方法改写了。

再比如我们可以在开发 Java Agent的时候使用这个伙计

public static void premain(String args, Instrumentation inst) {         AgentBuilder agentBuilder = new AgentBuilder.Default();         AgentBuilder.Transformer transformer = new AgentBuilder.Transformer() {             public DynamicType.Builder transform(DynamicType.Builder builder,                                                     TypeDescription typeDescription,                                                     ClassLoader classLoader, JavaModule javaModule) {                 String className = typeDescription.getCanonicalName();                 builder = builder.method(ElementMatchers.any())//匹配任意方法                             .intercept(MethodDelegation.to(new SimplePackageInstanceMethodInterceptor()));                 return builder;             }         };           agentBuilder = agentBuilder.type(ElementMatchers.nameStartsWith("com.example.hello.sample")).transform(transformer);         agentBuilder.installOn(inst);     }

在类里进行拦截匹配的时候,可以通过类名来限定,同时以不同的模式去匹配方法名等,这里的ElementMatchers可以用在类名与方法名等匹配场景中

//ElementMatchers.named("abc") // 特定名称的方法 //ElementMatchers.nameStartsWith("hello")  // 以什么开头的 //ElementMatchers.nameEndsWith("test")   // 以什么结尾的

我们看到前面的代码中 agentBuilder.installOn(inst);

通过 JavaAgent的Instrument 进行类修改。

AgentBuilder 还提供了一个神奇的方法:

agentBuilder.installOnByteBuddyAgent();

这样无须提供 Jar 文件也一样能实现运行时增强。不过需要注意,这样使用时,一定要先执行这行代码,这也是其实现的秘密:

ByteBuddyAgent.install();

因为 ByteBuddy 自己做为一个 Jar 也 Attach ,然后再将其它后续的增强代码加入,像不像「特洛伊木马」 :)

另外, ByteBuddy 还支持类似于 AOP 的 Advice实现,在拦截指定方法后可以实现OnMethodEnter 和 OnMethodExit 的控制,在这其中,可以完成绕过用户代码,执行自定义内容的逻辑。

咱们在开始的时候,还提到了代码的生成。这在 ByteBuddy 看来也是易如反掌。

和上面的代码一样,先要拿到 AgentBuilder,之后在执行 tranform的时候,直接指定方法名,以及对应的参数,访问控制符等。

DynamicType.Builder.MethodDefinition.ExceptionDefinition hello =                                 builder.defineMethod(methodName, types, Visibility.PUBLIC)                                         .withParameters(m.getParameters().asTypeList());

再比如在运行时给一个方法增加注解,

builder.method(ElementMatchers.named("methodName")).intercept(SuperMethodCall.INSTANCE)                            .annotateMethod(AnnotationDescription.Builder.ofType(TestAnnotation.class)                                    .define("testValue", 123).build());

是不是功能很强大?

"不用Jar包的Agent的优点有哪些"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

方法 代码 字节 运行 工具 框架 动态 文件 时候 开发 不用 高级 人们 内容 官方 语言 还是 推荐 优点 简洁 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 苹果x连接不到服务器怎么解决 电商直播软件开发价格 深圳市易印网络技术开发 至强e5自制服务器 诉宝保网络技术有限公司 如何进行关系数据库的模式设计 网络技术通信有哪些技术指标 世界十大网络技术公司 2019高罗乡小型工程数据库 贵阳工程表格管理软件开发 河北java软件开发询问报价 北京汇融网络技术 邵阳软件开发中介 青浦区海航软件开发共同合作 网络安全三字经防骗篇 当前网络技术主流 国家网络安全周电脑关机 网络安全完善相关法律法规 编办网络安全和信息化 无锡可视化智慧学校软件开发 崇明区智能化软件开发制品价格 深化网络安全警示心得体会 江苏超频服务器操作 软件开发培训学校梦见 有关网络安全的谚语 对学生网络安全的措施 网络安全研究所怎么样 三级网络技术算中级吗 直接删除数据库会删到表吗 软件开发公司资质咨询
0