在深入代碼前,先建立統一術語:
MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice 等接口。JdkRegexpMethodPointcut 通過正則匹配方法名。DefaultPointcutAdvisor 持有 advice 和 pointcut 兩個屬性。ProxyFactoryBean 實現了 FactoryBean,其 getObject() 返回代理實例:
public Object getObject() throws BeansException {
initializeAdvisorChain(); // 解析 interceptorNames 構建 Advisor 鏈
return isSingleton() ? getSingletonInstance() : newPrototypeInstance();
}
private synchronized Object getSingletonInstance() {
if (singletonInstance == null) {
targetSource = freshTargetSource();
if (autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
setInterfaces(ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass()));
}
super.setFrozen(freezeProxy); // 凍結配置,禁止運行時修改
singletonInstance = getProxy(createAopProxy()); // 核心:創建 AopProxy 再獲取代理
addListener(this); // 監聽 Advisor 變更以重建單例
}
return singletonInstance;
}
Spring 通過 AopProxy 接口屏蔽具體代理實現,DefaultAopProxyFactory 負責決策:
public AopProxy createAopProxy(AdvisedSupport advised) throws AopConfigException {
// 優先使用 CGLIB 的條件
if (advised.isOptimize() || advised.isProxyTargetClass() || advised.getProxiedInterfaces().length == 0) {
if (!cglibAvailable) throw new AopConfigException("CGLIB2 not available...");
return CglibProxyFactory.createCglibProxy(advised);
} else {
return new JdkDynamicAopProxy(advised); // 默認 JDK 動態代理
}
}
決策矩陣:
| 場景 | 代理類型 | 觸發條件 |
|---|---|---|
| 目標實現了接口,無特殊配置 | JDK Dynamic Proxy | 默認 |
| 目標未實現接口 | CGLIB | proxiedInterfaces.length == 0 |
| 強制代理目標類 | CGLIB | proxyTargetClass=true |
| 優化模式 | CGLIB | optimize=true |
public Object getProxy(ClassLoader classLoader) {
Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); // 處理 equals/hashCode
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); // this = InvocationHandler
}
關鍵點:
InvocationHandler,所有代理方法調用轉發到 invoke()(見第 1 篇文章詳細分析)。completeProxiedInterfaces 會自動補全 SpringProxy、Advised、DecoratingProxy 等標記接口。核心邏輯:
Enhancer 創建目標類的子類。CallbackFilter 區分不同方法的攔截策略(如 equals/hashCode 走 FixedValue,業務方法走 MethodInterceptor)。Objenesis 繞過構造函數實例化代理類(避免目標類無無參構造函數報錯)。FastClass 機制加速方法調用(索引直達,避免反射開銷)。ProxyFactoryBean 繼承自 AdvisedSupport,後者維護:
advisorChain:List 有序攔截器鏈。targetSource:TargetSource 目標對象提供者(支援單例、原型、池化、熱換)。interfaces:代理需實現的接口數組。proxyTargetClass/optimize:代理策略標記。frozen:配置凍結標記。所有 AOP 配置最終都匯聚到此對象,JdkDynamicAopProxy 和 CglibAopProxy 均以此為輸入構建代理。
SingletonTargetSource:單例模式,持有固定目標實例。PrototypeTargetSource:每次調用 getTarget() 從 BeanFactory 獲取新實例。PoolingTargetSource:對象池模式,getTarget() 借對象,releaseTarget() 還對象。HotSwappableTargetSource:運行時熱換目標對象,無需重建代理。這正是 Spring AOP 支援「目標對象生命週期與代理生命週期解耦」的關鍵設計。
ProxyFactoryBean.getObject() → initializeAdvisorChain() 解析配置構建 Advisor 鏈。getSingletonInstance() → createAopProxy() → DefaultAopProxyFactory.createAopProxy() 選型。new JdkDynamicAopProxy(advised) → Proxy.newProxyInstance(..., this)。Enhancer.create() + CallbackFilter + MethodInterceptor。AdvisedSupport 引用,方法調用轉發到統一攔截入口(JDK 為 InvocationHandler.invoke,CGLIB 為 MethodInterceptor.intercept)。ReflectiveMethodInvocation / CglibMethodInvocation 執行責任鏈。理解這條鏈路,能幫助你快速定位:為什麼代理沒生效?為什麼報 AopConfigException?為什麼 final 方法不被攔截?為什麼自我調用失效?——所有答案都在這條創建與調用鏈中。