首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 反射與動態代理:Spring IoC/AOP 核心基石

     編輯:Java 綜合教學

核心定位

Java 反射機制與動態代理是**元編程**能力的體現,使運行時檢測/修改類行為成為可能。Spring 核心 —— **IoC 容器(依賴注入)** 與 **AOP 切面編程** —— 均建立在這兩大技術之上。

反射機制核心 API

核心類核心能力典型場景
Class<T>類元數據入口:字段/方法/構造器/註解/泛型信息框架掃描組件、序列化/反序列化
Field字段訪問:獲取/設置值、修飾符、泛型類型ORM 映射、配置屬性注入
Method方法調用:invoke、參數/返回類型、異常、註解事件總線、RPC 代理、AOP 切點匹配
Constructor<T>實例化:newInstance、參數類型、訪問權限繞過IoC 容器創建 Bean、反序列化

動態代理兩大實現

1. JDK 動態代理(接口代理)

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;
    }
);
  • **前提**:目標類必須實現接口
  • **原理**:生成繼承 `Proxy`、實現目標接口的匿名類,委派 `InvocationHandler`
  • **限制**:無法代理非接口方法、final 方法、私有方法

2. CGLIB 代理(類代理)

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();
  • **原理**:繼承目標類,重寫非 final 方法,攔截調用
  • **優勢**:無需接口、性能略優於 JDK(FastClass 機制)
  • **限制**:無法代理 final 類/方法、構造函數會被調用兩次

Spring 中的實際應用

IoC 容器:反射驅動的 Bean 生命周期

  1. 掃描發現:ClassPathScanningCandidateComponentProvider 反射讀取註解(@Component 等)
  2. 實例化:ConstructorResolver 反射調用構造器(含參數解析、自動裝配)
  3. 屬性填充:AutowiredAnnotationBeanPostProcessor 反射注入字段/Setter
  4. 初始化回調:反射調用 @PostConstruct、InitializingBean.afterPropertiesSet()

AOP 框架:動態代理織入切面

  • 默認策略:**目標類實現接口 → JDK 代理**;**否則 → CGLIB**
  • 可強制 `` 全局使用 CGLIB
  • 切點表達式解析 → 反射匹配 Method → 生成代理鏈(Interceptor Chain)
  • 環繞通知(@Around)本質是 `MethodInterceptor` 實現

性能與避坑指南

誤區真相優化建議
反射極慢JDK 7+ 引入 MethodHandle + invokedynamic,熱點代碼 JIT 優化後與直接調用差距微小緩存 Class/Method/Field 對象;高頻調用用 MethodHandle/VarHandle
動態代理無損性能代理增加方法調用層級,攔截器鏈越長開銷越大精簡切面;熱點路徑考慮編譯期織入
setAccessible(true) 總安全JDK 9+ 模塊化系統限制深度反射,需 `--add-opens` 或開啟 `--permit-illegal-access`避免破壞封裝;框架開發者適配模塊化

總結

反射賦予了 Java「運行時自我認知」的能力,動態代理實現了「無侵入行為增強」。Spring 將二者封裝為**聲明式編程模型**,讓業務開發者專注領域邏輯。理解底層原理,不僅能排查框架級 Bug,更能在造輪子時做出正確架構決策。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved