《Spring in Action》前三章筆記精華,涵蓋 Bean 定義與裝配細節(集合、null、構造器注入、自動裝配)、BeanPostProcessor/BeanFactoryPostProcessor 生命週期擴展、國際化、事件機制、AOP 代理創建原理、切點類型、通知類型、代理工廠配置、自動代理創建器等核心知識點。
Bean 裝配細節速查表
| 場景 | XML 配置 | 關鍵點 |
| 引用其他 Bean | <ref bean="xxx"/> / local / parent | local 驗證同文件存在性,parent 訪問父上下文 |
| List/Set/Array 注入 | <list><value>...</list> 或 <set> | 互換使用,Spring 自動轉換目標集合類型 |
| Map 注入 | <entry key="k"><value>v</value></entry> | Key 僅支援 String,Value 任意類型 |
| Properties 注入 | <prop key="k">v</prop> | Key/Value 均為 String |
| 注入 null | <property name="x"><null/></property> | 區別於字串 "null" |
| 構造器注入多參數 | <constructor-arg index="0" value="..."/> | index 解決歧義,type 亦可但不如 index 通用 |
| 自動裝配 | <bean autowire="byName|byType|constructor|autodetect"> | 不建議生產使用,隱性依賴難追蹤;手動優先於自動 |
生命週期擴展點
BeanPostProcessor:Bean 實例化前後攔截
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName);
Object postProcessAfterInitialization(Object bean, String beanName);
}
- 在
BeanFactory 註冊:factory.addBeanPostProcessor(processor)。
ApplicationContext 自動檢測並註冊所有 BeanPostProcessor 型 Bean。
- 內建
ApplicationContextAwareProcessor 處理 ApplicationContextAware 回調。
BeanFactoryPostProcessor:Bean 定義階段修改元數據
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory);
}
- 在
BeanFactory 載入定義後、實例化前調用。
ApplicationContext 只需定義 Bean 即可自動啟用(無需手動註冊)。
- 典型應用:
PropertyPlaceholderConfigurer 解析 ${prop} 佔位符。
PropertyPlaceholderConfigurer 外部化配置
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"/>
</bean>
<bean id="dataSource" class="...">
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
</bean>
CustomEditorConfigurer 註冊自定義屬性編輯器
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date"><bean class="com.example.CustomDateEditor"/></entry>
</map>
</property>
</bean>
AOP 核心機制
代理創建策略
- 目標實現介面 → JDK 動態代理 (
java.lang.reflect.Proxy)。
- 目標無介面/強制 CGLIB → CGLIB 生成子類(final 方法不可攔截)。
- Spring 2.0+ 整合 AspectJ,支援更豐富切點表達式。
通知類型與介面
| 通知類型 | 介面 | 關鍵方法 | 特點 |
| 前置通知 | MethodBeforeAdvice | before(Method, Object[], Object) | 可拋異常阻止目標執行 |
| 後置通知 | AfterReturningAdvice | afterReturning(Object, Method, Object[], Object) | 獲得返回值,不可修改 |
| 環繞通知 | MethodInterceptor | invoke(MethodInvocation) → proceed() | 完全控制,可修改參數/返回值/拋異常 |
| 拋出通知 | ThrowsAdvice | afterThrowing(Throwable) / afterThrowing(Method, Object[], Object, Throwable) | 無介面方法定義,靠反射匹配方法名(設計缺陷) |
| 引介通知 | IntroductionInterceptor | 實現介面動態添加到目標 | 複雜,建議改用 AspectJ @DeclareParents |
切點類型
- 靜態切點:
NameMatchMethodPointcut(方法名通配符)、RegexpMethodPointcut(正則匹配類+方法)。
- 動態切點:
ControlFlowPointcut(檢查調用棧,效能極差,JDK 1.4 慢 5 倍,1.3 慢 10 倍),非必要勿用。
ProxyFactoryBean 完整配置
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="targetBean"/>
<property name="interceptorNames">
<list>
<value>advisor1</value>
<value>interceptor2</value>
<value>targetBean</value> <!-- 目標 Bean 也可放在列表最後 -->
</list>
</property>
<property name="proxyTargetClass" value="true"/> <!-- 強制 CGLIB -->
</bean>
- 未設
proxyInterfaces 且 proxyTargetClass=true → CGLIB。
interceptorNames 支援 Advisor/Interceptor/Target Bean 混合。
自動代理創建器:零配置 AOP
| 創建器 | 適用切點來源 | 特點 |
| BeanNameAutoProxyCreator | Bean 名稱模式 | 簡單,按 Bean 名攔截 |
| DefaultAdvisorAutoProxyCreator | 容器中所有 Advisor | 最強大,掃描所有 Advisor 自動代理匹配 Bean,實現 BeanPostProcessor |
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean id="txAdvisor" class="...TransactionAttributeSourceAdvisor" .../>
<bean id="logAdvisor" class="...NameMatchMethodPointcutAdvisor" .../>
書中勘誤記錄
- P54
java.awt → java.util。
- P94
maidService 配置中 frequentCustomerAdvisor → frequentCustomerPointcutAdvisor。
- P108 後兩個
proxyInterfaces → interceptorNames。
關鍵收穫
- Bean 裝配掌握集合/Map/Properties/null/構造器注入細節,自動裝配慎用。
BeanPostProcessor(實例級)vs BeanFactoryPostProcessor(定義級)是兩大擴展支柱。
- AOP 代理策略:有介面用 JDK,無介面/強制用 CGLIB;final 方法不可攔截。
- 通知類型選擇:多數場景
MethodInterceptor(環繞)最靈活;ThrowsAdvice 設計有缺陷。
DefaultAdvisorAutoProxyCreator 實現「配置一次 Advisor,全局自動代理」,是聲明式事務/日誌/安全的基石。
- 上一篇文章: Spring 數據訪問核心筆記(二):JdbcTemplate 深度解析、批量操作、存儲過程與 ORM 整合模式
- 下一篇文章: 下一代 Java Applet 插件技術深度解析:JNLP 整合、架構重設計與 NASA World Wind 實戰案例
Copyright ©
程式碼之家 All Rights Reserved