思想無語言邊界:以 cglib 介紹 AOP 在 java 的一個實現方式

victor.x.qu發表於2020-12-16

0. 前言

上接:基於 Source Generators 做個 AOP 靜態編織小實驗

作為第三篇,我們基於cglib在java做一個簡單的aop例子, 以此簡單作為例子說一個思路在什麼樣的語言裡面都是共同的,這是骨,不要糾結什麼語言什麼實現,這只是皮。

同以前一樣,是個人隨筆,不是新手教學,不會教會別人怎麼使用cglib,只會給出官方文件,請自學成才。

內容安排如下:

  • cglib demo
  • 簡單介紹cglib原理

1. cglib demo

1.0 cglib 是什麼?

https://github.com/cglib/cglib/wiki 官方介紹地址

cglib 全名 Code Generation Library, 是個動態代理程式碼生成庫,用來在執行時 extend JAVA classes and implements interfaces。

1.1 demo

1.1.1 使用 cglib 建立代理類

    public static Object createProxy(Class clazz, MethodInterceptor interceptor) {
        try {
            Enhancer e = new Enhancer();
            e.setSuperclass(clazz);
            e.setCallback(interceptor);
            Object bean = e.create();
            return bean;
        } catch (Throwable e) {
            e.printStackTrace();
            throw new Error(e.getMessage());
        }
    }

1.1.2 實現AddOneInterceptor

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class AddOneInterceptor implements MethodInterceptor {
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        if(method.getReturnType() == int.class) {
            return ((Integer) methodProxy.invokeSuper(o, objects)) + 1;
        } else {
            return methodProxy.invokeSuper(o, objects);
        }
    }
}

1.1.3 測試

public class RealClass {
    public int Add(int i, int j)
    {
        return i + j;
    }
}
public static void main(String args[]) {
    RealClass proxy = (RealClass) createProxy(RealClass.class, new AddOneInterceptor());
    int i = 5;
    int j = 10;
    System.out.println(String.format("%s + %s = %s, but proxy is %s", i, j, i + j, proxy.Add(i, j)));
}

結果:

5 + 10 = 15, but proxy is 16

2. 簡單介紹cglib原理

原理一句話:動態生成一個類的子類作為代理類,在子類中擴充套件想要加入的功能。

底層基於ASM 一個位元組碼處理框架。

ASM 是一個 Java 位元組碼操控框架。它能被用來動態生成類或者增強既有類的功能。ASM 可以直接產生二進位制 class 檔案,也可以在類被載入入 Java 虛擬機器之前動態改變類行為。Java class 被儲存在嚴格格式定義的 .class 檔案裡,這些類檔案擁有足夠的後設資料來解析類中的所有元素:類名稱、方法、屬性以及 Java 位元組碼(指令)。ASM 從類檔案中讀入資訊後,能夠改變類行為,分析類資訊,甚至能夠根據使用者要求生成新類。

可以看 https://developer.ibm.com/zh/articles/j-lo-asm30/ 這篇文章完整了解ASM。

可以說 cglib 就是ASM在動態代理類的一個完整封裝框架。

相關文章