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在動態代理類的一個完整封裝框架。