java動態代理產生$Proxy0原始碼的操作

來源:互聯網
上載者:User

標籤:agent、proxy

  1. $Proxy該類是動態產生的,在啟動並執行時候產生。具體原始碼的提取參考的是:http://www.cnblogs.com/ctgulong/p/5011614.html?utm_source=tuicool&utm_medium=referral的blog


2.根據上面部落格的內容詳細寫一下產生原始碼的過程。參考之前的項目http://yinyueml.blog.51cto.com/4841237/1876473

1)首先需要一個agent的產生類。javaagent主要功能如下:

  • 可以在載入class檔案之前做攔截,對位元組碼做修改

  • 可以在運行期對已載入類的位元組碼做變更,但是這種情況下會有很多的限制,後面會詳細說

  • 還有其他一些小眾的功能

    • 擷取所有已經載入過的類,這個功能讓我們可以擷取到動態代理的產生類的class檔案,經過反編譯後就可以查看原始碼。

    • 擷取所有已經初始化過的類(執行過clinit方法,是上面的一個子集)

    • 擷取某個對象的大小

    • 將某個jar加入到bootstrap classpath裡作為高優先順序被bootstrapClassloader載入

    • 將某個jar加入到classpath裡供AppClassloard去載入

    • 設定某些native方法的首碼,主要在尋找native方法的時候做規則匹配

2)代碼如下

package jdkReview;import java.io.File;import java.io.FileOutputStream;import java.lang.instrument.ClassFileTransformer;import java.lang.instrument.IllegalClassFormatException;import java.lang.instrument.Instrumentation;import java.security.ProtectionDomain;public class CustomAgent implements ClassFileTransformer { //    public static void premain(String agentArgs, Instrumentation inst) {        inst.addTransformer(new CustomAgent());    }    @Override    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,            ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {        if (!className.startsWith("java") && !className.startsWith("sun")) {            // 既不是java也不是sun開頭的            // 匯出代碼            int lastIndexOf = className.lastIndexOf("/") + 1;            String fileName = className.substring(lastIndexOf) + ".class";            exportClazzToFile("D:/javacode/", fileName, classfileBuffer);            System.out.println(className + " --> EXPORTED Succeess!");        }            return classfileBuffer;    }    /**     *      * @param dirPath     *目錄以/結尾,且必須存在     * @param fileName     * @param data     */    private void exportClazzToFile(String dirPath, String fileName, byte[] data) {        try {            File file = new File(dirPath + fileName);            if (!file.exists()) {                file.createNewFile();                }                FileOutputStream fos = new FileOutputStream(file);            fos.write(data);            fos.close();            } catch (Exception e) {            System.out.println("exception occured while doing some file operation");            e.printStackTrace();        }    }}

3)將CustomAgent匯出為jar包,並且修改MANIFEST.MF檔案內容如下:

Manifest-Version: 1.0Premain-Class: jdkReview.CustomAgent

該配置主要是為了Premain-Class的作用就是表示帶有premain靜態方法的Class。

4)在運行使用java動態代理的Client類的時候加上jvm的參數

-javaagent:d:/customAgent.jar

然後運行後如下結果為:

proxyPattern/Client --> EXPORTED Succeess!proxyPattern/GamePlayer --> EXPORTED Succeess!proxyPattern/IGamePlayer --> EXPORTED Succeess!proxyPattern/GamePlayIH --> EXPORTED Succeess!com/sun/proxy/$Proxy0 --> EXPORTED Succeess!有人再用我的帳號登陸登陸使用者名稱:yinyueml;玩家:張三上線張三正在打怪。張三升級了

現在通過

exportClazzToFile("D:/javacode/", fileName, classfileBuffer);

中的配置路勁就可以找到$Proxy0.class的檔案。

5)通過jad.exe反編譯應用對$Proxy0.class進行反編譯就可以擷取到原始碼。

java動態代理產生$Proxy0原始碼的操作

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.