1. 程式人生 > 程式設計 >深入瞭解JVM位元組碼增強技術

深入瞭解JVM位元組碼增強技術

這篇文章主要介紹了深入瞭解JVM位元組碼增強技術,文中通過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

JVM——位元組碼增強技術簡介

Java位元組碼增強指的是在Java位元組碼生成之後,對其進行修改,增強其功能,這種方式相當於對應用程式的二進位制檔案進行修改。Java位元組碼增強主要是為了減少冗餘程式碼,提高效能等。

實現位元組碼增強的主要步驟為:

1、修改位元組碼

在記憶體中獲取到原來的位元組碼,然後通過一些工具(如 ASM,Javaasist)來修改它的byte[]陣列,得到一個新的byte陣列。

2、使修改後的位元組碼生效

有兩種方法:

1) 自定義ClassLoader來載入修改後的位元組碼;

2)替換掉原來的位元組碼:在JVM載入使用者的Class時,攔截,返回修改後的位元組碼;或者在執行時,使用Instrumentation.redefineClasses方法來替換掉原來的位元組碼;

3. 兩種實現機制:

(1) 通過建立原始類的一個子類(動態建立的類繼承原來的類)。子類名以原始類名為字首,以避免重名。Spring AOP 使用的就是這種

(2) 直接修改原始類的位元組碼。類的跟蹤過程中使用

4. 實現位元組碼增強要執行兩個步驟:

(1) 在記憶體中獲取到原始的位元組碼, 然後通過一些開源的API 來修改它的byte[] 陣列,得到一個新的byte[] 陣列。

(2) 將新的byte[] 陣列載入到PermGen 區(即載入新的byte[] 陣列或替換原始類的位元組碼)。

介面 BCInterface

public interface BCInterface {
  void enhancement();
}

實現類 BCEnhancement.java

public class BCEnhancement implements BCInterface{
  public void enhancement() {
    System.out.println("hello enhancement");
  }
}
 

LogProxy.java

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class LogProxy implements InvocationHandler {
  private Object object;
  public Object getProxyObject(Object o){
    object=o;
    try{
      return Proxy.newProxyInstance(this.getClass().getClassLoader(),o.getClass().getInterfaces(),this);
    }catch (IllegalArgumentException e){
      throw new RuntimeException(e);
    }
  }
  public Object invoke(Object proxy,Method method,Object[] args) throws Throwable {
    System.out.println("before invoke ...");
    Object result= method.invoke(object,args);
    System.out.println("after invoke ...");
    return result;
  }
}

測試類 Test.java

public class Test {
  public static void main(String[] args) {
    LogProxy logProxy = new LogProxy();
    System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
    BCInterface byteCodeEn = (BCInterface) logProxy.getProxyObject(new BCEnhancement());
    byteCodeEn.enhancement();
  }
}

輸出:

before invoke ...
hello enhancement
after invoke ...

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。