new B() 或 JNDI 查找 → A 與 B 緊耦合,生命周期由 A 控制對象創建、銷毀、依賴綁定 控制權從業務代碼轉移到 Spring 容器,實現低耦合、高內聚、易測試、易擴展。
| 方式 | 特點 | 優勢 | 劣勢 | 推薦度 |
|---|---|---|---|---|
| 接口注入 | 實現特定接口 | 標準化 | 侵入性強、靈活性差 | ❌ Spring 不支持 |
| Setter 注入 | setXxx() 方法 | 可讀性強、支持可選依賴、循環依賴友好 | 對象構建過程中可能處於不完整狀態 | ★★★★☆ |
| 構造器注入 | 構造函數參數 | 構造期即完整、依賴不可變、強制依賴明確 | 參數過多時構造函數膨脹、循環依賴難處理 | ★★★★★ |
最佳實踐:強制依賴用構造器注入,可選依賴用 Setter 注入(Spring 4.0+ 推薦)。
橫切關注點:日誌、事務、安全、異常處理……分散在各業務模塊,導致代碼重復、耦合度高。
| 術語 | 含義 | Spring 實現 |
|---|---|---|
| Aspect (切面) | 橫切邏輯模塊化 | @Aspect + Advisor/Interceptor |
| Joinpoint (連接點) | 程序執行具體點(方法調用、異常拋出) | 方法執行 |
| Advice (通知) | 切面在連接點執行的動作 | Before/After/AfterReturning/AfterThrowing/Around |
| Pointcut (切入點) | 匹配連接點的表達式 | @Pointcut、正則、AspectJ 表達式 |
| Target (目標對象) | 被代理的業務對象 | POJO |
| Proxy (代理) | 織入切面後的代理對象 | JDK Dynamic Proxy / CGLIB |
| Weaving (織入) | 將切面應用到目標對象 | 運行時動態織入 |
@Before:方法前執行(不可阻止執行)@AfterReturning:正常返回後執行@Around:環繞全過程,可控制是否執行目標方法、修改參數/返回值(最強大)@AfterThrowing:拋出異常後執行@After:最終執行(類似 finally)入口:new ClassPathXmlApplicationContext("applicationContext.xml") → AbstractApplicationContext.refresh()
DefaultListableBeanFactory@Autowired、@Value 等)BeanDefinition
ContextRefreshedEvent,啟動生命周期處理器實現 ApplicationListener<ContextRefreshedEvent>:
@Component
public class StartupListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// 容器初始化/刷新完成時觸發
// 執行啟動後初始化任務:預熱緩存、啟動調度任務、註冊服務等
}
}
事件廣播機制:ApplicationEventMulticaster.multicastEvent() → 遍歷所有 ApplicationListener 異步/同步調用。
| 概念 | 本質 | 區別 |
|---|---|---|
| BeanFactory | IOC 容器核心接口 | 管理 Bean 定義、依賴關系、生命周期的「超級工廠」 |
| FactoryBean | 特殊 Bean 類型 | getObject() 返回的才是真正注入的對象,而非 FactoryBean 本身 |
典型應用:SqlSessionFactoryBean、DataSourceFactoryBean 等封裝複雜創建邏輯。
實例化 → 屬性填充 → 初始化前後置處理器 → 初始化方法 → AOP 代理 → 放入單例池 → 使用中 → 銷毀前置處理器 → 銷毀方法 → 移出容器
postProcessBeforeInstantiation():實例化前,返回非 null 可跳過默認創建(AOP 代理生成點)postProcessAfterInstantiation():實例化後,屬性填充前postProcessBeforeInitialization():初始化方法前postProcessAfterInitialization():初始化方法後(AOP 代理包裝點)singleton(默認):容器啟動創建,完整生命周期prototype:每次 getBean() 創建,**容器不管理銷毀**(需客戶端自行清理)lazy-init="true":延遲到首次獲取時創建在 Bean 實例化前修改 BeanDefinition 元數據:
PropertyPlaceholderConfigurer:解析 ${xxx} 佔位符ConfigurationClassPostProcessor:解析 @Configuration、@ComponentScan 等註解調用鏈:refresh() → invokeBeanFactoryPostProcessors() → 排序 → 逐個 postProcessBeanFactory()。
核心心法:Spring 容器本質是「BeanDefinition 註冊表 + 生命周期管理器 + 擴展點鏈」。掌握 BeanDefinition 元數據結構、PostProcessor 擴展機制、AOP 代理生成時機,即掌握了 Spring 的靈魂。