Java Agents代理是什么
表示Java Agents
的類(lèi)顯然只不過(guò)是Java API
庫(kù)中的任何其他類(lèi)。但是,讓它們與眾不同的是,它們遵循某種約定,這種約定使Java代碼能夠攔截JVM中運(yùn)行的另一個(gè)應(yīng)用程序。其目的只是讓代理調(diào)查或修改字節(jié)碼。這是一個(gè)強(qiáng)大但不可思議的特性,超出了Java程序通常的功能范圍。在某種程度上,它可以闖入一個(gè)程序,修改字節(jié)碼或造成混亂。請(qǐng)理解,這不是添加到Java中的新技術(shù)或功能。自JDK1.5以來(lái),它一直是庫(kù)的一部分。這意味著使用它們也有一些真正的好處。但是,在討論它們的優(yōu)點(diǎn)以及如何使用它們之前,讓我們先看看在Java中哪里可以找到它們。
一、Java Agents 和 Instrumentation
Java agent
是Java Instrumentation API
的一部分。檢測(cè)API提供了一種修改方法字節(jié)碼的機(jī)制。這可以靜態(tài)和動(dòng)態(tài)地完成。這意味著我們可以通過(guò)向程序中添加代碼來(lái)更改程序,而不必涉及程序的實(shí)際源代碼。結(jié)果可能會(huì)對(duì)應(yīng)用程序的整體行為產(chǎn)生重大影響。
Java agent
和instrumentation API
位于名為 Java.lang.intrumentation
的包中。
二、Java agent的使用
Java agent
可以有多種用途,如面向方面編程(AOP)、變異測(cè)試、評(píng)測(cè)等。AOP通常會(huì)在不更改代碼的情況下向現(xiàn)有程序添加日志記錄或安全性等行為。它使用Java代理來(lái)操作字節(jié)碼,并將其功能與程序結(jié)合起來(lái)。監(jiān)視JVM級(jí)別的參數(shù),如對(duì)象創(chuàng)建、垃圾收集、線程執(zhí)行等,是探查器的工作。評(píng)測(cè)工具顯著地使用Java代理評(píng)測(cè)執(zhí)行中程序的JVM參數(shù)。
還有許多其他情況下,Java agent
和instrumentation API
非常方便。
三、如何編寫(xiě)Java代理
實(shí)現(xiàn)Java agent
的類(lèi)必須實(shí)現(xiàn)一個(gè)名為
public static void premain(String agentArgs, Instrumentation inst)
此方法構(gòu)成代理的入口點(diǎn),就像常規(guī)Java程序的入口點(diǎn)是主方法一樣。
JVM初始化后,調(diào)用 premain
方法;這表示代理??梢杂袔讉€(gè)這樣的代理;因此,將根據(jù)JVM初始化期間指定的代理的順序調(diào)用每個(gè) premain
方法。如果找不到特定的 premain
方法,JVM會(huì)依次調(diào)用 premain
方法的重載版本,例如
public static void premain(String agentArgs)
代理類(lèi)還可能包含JVM在agent啟動(dòng)后通常使用的方法,例如
public static void agentmain(String agentArgs, instrumentation inst)
或者,它的重載版本
public static void agentmain(String agentArgs)
這是JVM的典型例程,一旦該例程完成,就會(huì)調(diào)用 main 方法。
另一件重要的事情是,Java代理在開(kāi)發(fā)期間必須在資源目錄的 META-INF 文件夾中包含 MANIFEST.MF 文件。此文件包含有關(guān)包分發(fā)的元數(shù)據(jù)信息。此文件作為其JAR打包的一部分包含。 MANIFEST.MF 文件中包含的屬性提供了有關(guān)為什么需要這樣做的線索。這些屬性如下所示:
Premain-class
:此屬性定義代理類(lèi)。如果未定義此屬性,JVM將中止。Agent-class
:它定義了在JVM啟動(dòng)后啟動(dòng)Java
代理的機(jī)制。如果此屬性未定義,代理將不會(huì)啟動(dòng)。Can-Redefine-Classes
:這定義了代理重新定義類(lèi)的能力。該值可以是true
或false
。Can-Retransform-Classes
:這定義了代理重新傳輸類(lèi)的能力。該值可以是true
或false
。Can-Set-Native-Method-Prefix
:這定義了代理設(shè)置本機(jī)方法前綴的能力。該值可以是true
或false
。Boot-Class-Path
:定義引導(dǎo)類(lèi)加載程序的搜索路徑列表。
一個(gè)簡(jiǎn)單的例子:
探查器工具通常通過(guò)從JVM提取信息來(lái)報(bào)告運(yùn)行時(shí)Java對(duì)象的不同參數(shù)。這些參數(shù)包括關(guān)于使用檢測(cè)框架的對(duì)象的內(nèi)存使用等信息。
1. 這里我們使用 premain
方法創(chuàng)建一個(gè)代理類(lèi)。
2. 傳遞給 premain
方法的檢測(cè)實(shí)例將提供有關(guān)對(duì)象大小的信息。
3. 將代理類(lèi)與 MANIFEST.MF
文件一起打包到JAR文件中。
4. 使用命令行參數(shù)將代理傳遞給JVM。
這是我們將在示例中使用的示例類(lèi)。這沒(méi)什么特別的。
package com.mano.examples; public class Main { public static void greet(String msg){ System.out.println(msg); } public static void main(String[] args){ greet("Hello Agents"); } }
四、代理類(lèi)
帶有 premain
方法的instrumentation agent
類(lèi)用于檢索我們需要的信息。插裝接口的實(shí)現(xiàn)被傳遞給 premain
方法。我們使用由instrumentation
接口定義的 getObjectSize
方法來(lái)獲取運(yùn)行時(shí)主對(duì)象的內(nèi)存使用情況。
package com.mano.examples; import java.lang.instrument.Instrumentation; public class MyAgentClass { public static void premain(String agentArgs, Instrumentation inst) { System.out.println(inst.getObjectSize (new Main())) } }
之后,我們必須創(chuàng)建 MANIFEST.MF
文件。這只是一個(gè)文本文件,我們?cè)谄渲蟹胖门c代理類(lèi)相關(guān)的信息。JVM將使用它來(lái)加載代理。該文件通常存儲(chǔ)在 META-INF
目錄中。
我們的示例所需的內(nèi)容非?;荆?/strong>
Manifest-Version: 1.0 Premain-Class: com.mano.examples.MyAgentClass
現(xiàn)在,編譯所有Java文件以創(chuàng)建類(lèi)文件。最后,創(chuàng)建JAR文件,如下所示:
jar -cmf META-INF/MANIFEST.MF myagent.jar com/mano/examples/ MyAgentClass.class
五、部署Java Agents
創(chuàng)建代理后,它將作為JAR文件部署。清單文件中的屬性指定將加載以啟動(dòng)代理的代理類(lèi)。請(qǐng)注意,啟動(dòng)代理有很多方法:使用命令行、運(yùn)行時(shí)或作為JAR可執(zhí)行文件。我們將在這里使用命令行。
使用命令行運(yùn)行Agents
代理
命令行是:
java -javaagent:myagent.jar -cp . com.mano.examples.Main
這表示 premain
方法將在應(yīng)用程序執(zhí)行之前運(yùn)行,并創(chuàng)建 Main 實(shí)例的大小。
結(jié)論:
儀器API所提供的功能可以進(jìn)行多種創(chuàng)新。AOP是一個(gè)簡(jiǎn)單的例子。雖然Java
代理和Java Instrumentation API
在應(yīng)用程序開(kāi)發(fā)中不經(jīng)常使用,但是關(guān)于它的全部?jī)?nèi)容的想法可以澄清Java
的許多其他方面。這里給出的代碼示例是初步的,只是為了說(shuō)明如何創(chuàng)建代理。
到此這篇關(guān)于Java Agents
代理是什么的文章就介紹到這了,更多相關(guān)Java Agents
代理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
簡(jiǎn)單了解Java中多態(tài)的基礎(chǔ)知識(shí)
這篇文章主要介紹了簡(jiǎn)單了解Java中的多態(tài),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09Java實(shí)現(xiàn)操作JSON的便捷工具類(lèi)完整實(shí)例【重寫(xiě)Google的Gson】
這篇文章主要介紹了Java實(shí)現(xiàn)操作JSON的便捷工具類(lèi),基于重寫(xiě)Google的Gson實(shí)現(xiàn),涉及java針對(duì)json數(shù)據(jù)的各種常見(jiàn)轉(zhuǎn)換操作實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-10-10Java使用正則表達(dá)式截取重復(fù)出現(xiàn)的XML字符串功能示例
這篇文章主要介紹了Java使用正則表達(dá)式截取重復(fù)出現(xiàn)的XML字符串功能,涉及java針對(duì)xml字符串及指定格式字符串的正則匹配相關(guān)操作技巧,需要的朋友可以參考下2017-08-08深扒Java中POJO、VO、DO、DTO、PO、BO、AO、DAO的概念和區(qū)別以及如何應(yīng)用
po vo bo dto dao 和 pojo 是軟件開(kāi)發(fā)中經(jīng)常使用的一些概念,用于設(shè)計(jì)和實(shí)現(xiàn)對(duì)象模型,下面將分別解釋這些概念的含義及其在開(kāi)發(fā)中的應(yīng)用,這篇文章主要給大家介紹了關(guān)于Java中POJO、VO、DO、DTO、PO、BO、AO、DAO的概念和區(qū)別以及如何應(yīng)用的相關(guān)資料,需要的朋友可以參考下2024-08-08mybatis多層嵌套resultMap及返回自定義參數(shù)詳解
這篇文章主要介紹了mybatis多層嵌套resultMap及返回自定義參數(shù)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12IDEA設(shè)置生成帶注釋的getter和setter的圖文教程
通常我們用idea默認(rèn)生成的getter和setter方法是不帶注釋的,當(dāng)然,我們同樣可以設(shè)置idea像MyEclipse一樣生成帶有Javadoc的模板,具體設(shè)置方法,大家參考下本文2018-05-05idea沒(méi)有services窗口、沒(méi)有springboot啟動(dòng)項(xiàng)問(wèn)題
這篇文章主要介紹了idea沒(méi)有services窗口、沒(méi)有springboot啟動(dòng)項(xiàng)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05Java將科學(xué)計(jì)數(shù)法數(shù)據(jù)轉(zhuǎn)為字符串的實(shí)例
下面小編就為大家?guī)?lái)一篇Java將科學(xué)計(jì)數(shù)法數(shù)據(jù)轉(zhuǎn)為字符串的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12