Spring 框架的核心是 IoC (Inversion of Control,控制反轉) 與 DI (Dependency Injection,依賴注入)。本文通過示例梳理 Bean 的定義、實例化方式、作用域、生命週期回調以及 DI 的配置細節。
// 接口
public interface PersonInterface {
void show();
}
// 實現類
public class UserBean implements PersonInterface {
@Override
public void show() {
System.out.println("UserBean 實現了 PersonInterface 接口的 show 方法");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 核心配置:id 對應獲取時的名稱,class 為全限定類名 -->
<bean id="userBean" class="com.imooc.mybean.UserBean" />
</beans>
@Test
public void testUserBean() {
// 1. 創建容器,加載配置
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
// 2. 獲取 Bean
PersonInterface person = (PersonInterface) context.getBean("userBean");
// 3. 使用
person.show();
}
輸出: UserBean 實現了 PersonInterface 接口的 show 方法
| 方式 | 配置關鍵點 | 適用場景 |
|---|---|---|
| 構造器實例化 (最常用) | <bean id="..." class="全限定類名" />需提供無參構造器 |
普通 POJO,完全由容器管理 |
| 靜態工廠方法 | class="工廠類全限定名" factory-method="靜態方法名" |
對象創建邏輯複雜、需隱藏構造細節、單例模式獲取實例 |
| 實例工廠方法 | 1. 定義工廠 Bean:<bean id="factory" class="工廠類" />2. 引用工廠: <bean id="..." factory-bean="factory" factory-method="實例方法名" /> |
工廠本身需要配置屬性、有狀態、或需代理增強時 |
singleton (默認):**容器級單例**,啟動時或首次獲取創建,全局唯一。getBean 多次返回同一實例 (== 為 true)。prototype:**多例**,每次 getBean 或注入時創建新實例。request、session、application、websocket。<bean ... lazy-init="true" /> — 首次獲取時才創建。<beans default-lazy-init="true">。init-method="initMethodName" (對應 @PostConstruct 或 InitializingBean 接口)。destroy-method="destroyMethodName" (對應 @PreDestroy 或 DisposableBean 接口)。IoC: 創建對象的控制權從「應用程式碼」轉移到「Spring 容器」。
DI: 容器在創建對象時,將依賴關係「注入」到對象中 (Setter/構造器/字段)。
本質: 獲得依賴對象的方式被反轉了 — 從主動new變為被動接收。
// Service 依賴 Dao
public class UserServiceImpl implements UserService {
private UserDao userDao; // 接口類型,面向接口編程
// 必須提供 setter
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void show() {
userDao.show();
}
}
// spring.xml 配置
<bean id="mysqlDao" class="com.imooc.impl.UserDao4MysqlImpl" />
<bean id="oracleDao" class="com.imooc.impl.UserDao4OracleImpl" />
<bean id="userService" class="com.imooc.impl.UserServiceImpl">
<!-- ref 引用另一個 bean 的 id -->
<property name="userDao" ref="mysqlDao" />
</bean>
運行測試,輸出 UserDao4MysqlImpl。若需切換 Oracle,只需修改配置文件 ref="oracleDao",業務代碼零修改,實現了解耦。
<constructor-arg ref="..." /> — 強依賴、不可變對象首選。<bean ... p:userDao-ref="mysqlDao" /> (需引入 p namespace)。autowire="byType" 或 byName — 便利但降低可讀性,大型項目慎用。BeanFactory / ApplicationContext 管理 Bean 生命週期。