IoC (Inversion of Control) 與 DI (Dependency Injection) 是 Spring 框架的基石。本文系統梳理 Spring IoC 容器體系、Bean 配置方式、依賴注入模式、高級特性 (自動裝配、繼承、作用域、SpEL、生命週期、FactoryBean)、注解驅動開發等核心知識點,構建完整知識圖譜。
| 容器類型 | 核心實現類 | 特點 |
|---|---|---|
| BeanFactory | DefaultListableBeanFactory | IOC 基礎實現,延遲加載,Spring 內部使用 |
| ApplicationContext | ClassPathXmlApplicationContext FileSystemXmlApplicationContext AnnotationConfigApplicationContext | 高級功能:國際化、事件發布、資源加載、啟動時實例化所有單例 Bean |
| WebApplicationContext | XmlWebApplicationContext | Web 專用,從 WEB-INF 相對路徑加載,綁定 ServletContext |
啟動流程:實例化容器 → 加載配置元數據 (XML/注解/JavaConfig) → 解析 BeanDefinition → 實例化 Bean → 填充屬性 → 初始化 (回調) → 註冊銷毀回調 → 可用。
<bean id="msg" class="java.lang.String">
<constructor-arg value="hello"/>
</bean>
<bean id="hello" class="com.demo.Hello">
<property name="msg" ref="msg"/>
</bean>
<constructor-arg>,保證構造後即可用,強依賴首選。<property name="xxx" value/ref="..."/>,最常用,可選依賴。factory-method + factory-bean/class,較少用。<property name="list"> <list><value>a</value><ref bean="b"/></list> </property> <property name="set"> <set>...</set> </property> <property name="map"> <map><entry key="k" value="v"/></map> </property> <property name="props"> <props><prop key="k">v</prop></props> </property>
<beans xmlns:p="https://www.springframework.org/schema/p">
<bean id="hello" class="com.demo.Hello" p:msg="hello" p:msg-ref="msg"/>
</beans>
autowire="byType":按類型匹配,多候選報錯。autowire="byName":按屬性名匹配 Bean id。<bean id="parent" class="com.demo.Person" p:name="Tom" p:age="20"/> <bean id="child" parent="parent" p:name="Jerry"/>
abstract="true" 僅作模板不實例化。
| scope | 含義 | 場景 |
|---|---|---|
| singleton | 容器內單例 (默認) | 無狀態服務、DAO、Controller |
| prototype | 每次 getBean 新建 | 有狀態對象、命令對象 |
| request/session/application | Web 作用域 | Web 相關組件 |
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbcUrl}"/> ...
</bean>
<property name="count" value="#{5}"/>
<property name="name" value="#{otherBean.name}"/>
<property name="max" value="#{T(java.lang.Math).max(1,2)}"/>
<property name="flag" value="#{systemProperties['os.name'].contains('Windows')}"/>
@PostConstruct / InitializingBean.afterPropertiesSet() / init-method@PreDestroy / DisposableBean.destroy() / destroy-methodFactoryBean<T> 接口,getObject() 返回真實 Bean 實例。容器管理的是 FactoryBean 本身,getBean("id") 返回 getObject() 結果,getBean("&id") 返回 FactoryBean 實例。class="FactoryClass" factory-method="staticMethod"。factory-bean="factoryInstance" factory-method="instanceMethod"。| 注解 | 語義 | 層級 |
|---|---|---|
@Component | 通用組件 | 任意 |
@Repository | 持久層 (自動異常轉換) | DAO |
@Service | 業務層 | Service |
@Controller | 表現層 | Web |
<context:component-scan base-package="com.demo"
resource-pattern="**/service/*.class">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
@Autowired:按類型裝配,構造器/字段/方法均可。required=false 允許缺失。配合 @Qualifier("beanName") 解決多候選。@Resource:JSR-250,按名稱裝配 (name 屬性),其次類型。@Inject:JSR-330,同 @Autowired 但無 required 屬性。Spring IoC 以「容器管理 Bean 生命週期與依賴關係」為核心,從 XML 顯式配置演進至注解掃描與 JavaConfig,本質未變。掌握 BeanDefinition 解析、生命週期回調、後置處理器擴展機制、作用域與自動裝配原理,是深度使用 Spring、排查疑難雜症、設計擴展框架的關鍵。