Java 反射機制與動態代理是**元編程**能力的體現,使運行時檢測/修改類行為成為可能。Spring 核心 —— **IoC 容器(依賴注入)** 與 **AOP 切面編程** —— 均建立在這兩大技術之上。
| 核心類 | 核心能力 | 典型場景 |
|---|---|---|
| Class<T> | 類元數據入口:字段/方法/構造器/註解/泛型信息 | 框架掃描組件、序列化/反序列化 |
| Field | 字段訪問:獲取/設置值、修飾符、泛型類型 | ORM 映射、配置屬性注入 |
| Method | 方法調用:invoke、參數/返回類型、異常、註解 | 事件總線、RPC 代理、AOP 切點匹配 |
| Constructor<T> | 實例化:newInstance、參數類型、訪問權限繞過 | IoC 容器創建 Bean、反序列化 |
public interface UserService { void save(); }
public class UserServiceImpl implements UserService { ... }
// 運行時生成實現 UserService 的代理類
UserService proxy = (UserService) Proxy.newProxyInstance(
UserService.class.getClassLoader(),
new Class[]{UserService.class},
(proxyObj, method, args) -> {
System.out.println("事務開啟");
Object result = method.invoke(target, args);
System.out.println("事務提交");
return result;
}
);
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserServiceImpl.class);
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
System.out.println("事務開啟");
Object result = proxy.invokeSuper(obj, args);
System.out.println("事務提交");
return result;
});
UserService proxy = (UserService) enhancer.create();
| 誤區 | 真相 | 優化建議 |
|---|---|---|
| 反射極慢 | JDK 7+ 引入 MethodHandle + invokedynamic,熱點代碼 JIT 優化後與直接調用差距微小 | 緩存 Class/Method/Field 對象;高頻調用用 MethodHandle/VarHandle |
| 動態代理無損性能 | 代理增加方法調用層級,攔截器鏈越長開銷越大 | 精簡切面;熱點路徑考慮編譯期織入 |
| setAccessible(true) 總安全 | JDK 9+ 模塊化系統限制深度反射,需 `--add-opens` 或開啟 `--permit-illegal-access` | 避免破壞封裝;框架開發者適配模塊化 |
反射賦予了 Java「運行時自我認知」的能力,動態代理實現了「無侵入行為增強」。Spring 將二者封裝為**聲明式編程模型**,讓業務開發者專注領域邏輯。理解底層原理,不僅能排查框架級 Bug,更能在造輪子時做出正確架構決策。