在 Spring 框架中,Bean 的作用域、依賴注入方式、自動裝配機制以及生命週期管理是開發者必須掌握的核心知識點。本文將通過實際代碼示例,深入解析這四大主題。
Spring 通過 scope 屬性定義 Bean 的生命週期範圍,最常用的有兩種:
getBean() 時,容器都會創建一個新的 Bean 實例。<bean id="userService" class="ml.orlion.service.UserService" scope="prototype">
<property name="userDao" ref="userDao"/>
</bean>
測試代碼:
BeanFactory appContext = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) appContext.getBean("userService");
UserService userService2 = (UserService) appContext.getBean("userService");
System.out.println(userService == userService2); // 輸出 false
由於設置為 prototype,兩次獲取的實例不相同。
Spring 支持注入 List、Set、Map 等集合類型。以下以 UserDAOImpl 為例:
public class UserDAOImpl implements UserDAO {
private Set<String> sets;
private List<String> lists;
private Map<String, String> maps;
// getter/setter 省略
public String toString() {
return sets.size() + "|" + lists.size() + "|" + maps.size();
}
}
<bean id="userDao" class="ml.orlion.dao.impl.UserDAOImpl">
<property name="sets">
<set>
<value>1</value>
</set>
</property>
<property name="lists">
<list>
<value>1</value>
<value>2</value>
</list>
</property>
<property name="maps">
<map>
<entry key="1" value="1"/>
<entry key="2" value="2"/>
<entry key="3" value="3"/>
</map>
</property>
</bean>
BeanFactory appContext = new ClassPathXmlApplicationContext("beans.xml");
UserDAO userDao = (UserDAO) appContext.getBean("userDao");
System.out.println(userDao); // 輸出 1|2|3
Spring 提供 autowire 屬性實現依賴自動注入,常用模式有:
<bean id="userDao" class="ml.orlion.dao.impl.UserDAOImpl">
<property name="daoId" value="1"/>
</bean>
<bean id="userDao2" class="ml.orlion.dao.impl.UserDAOImpl">
<property name="daoId" value="2"/>
</bean>
<bean id="userService" class="ml.orlion.service.UserService" scope="prototype" autowire="byName">
</bean>
測試時,userService 中的 userDao 屬性會自動匹配 ID 為 userDao 的 Bean,輸出 daoId=1。
若全局統一自動裝配策略,可在 <beans> 根標籤使用 default-autowire 屬性。
Spring 管理 Bean 的完整生命週期,關鍵節點包括:
設置 lazy-init="true" 可使 Bean 在容器啟動時不初始化,而是首次請求時才創建。也可在 <beans> 上設置 default-lazy-init="true" 全局生效。
通過 init-method 和 destroy-method 指定自定義方法:
public class UserService {
public void init() { System.out.println("init"); }
public void destroy() { System.out.println("destroy"); }
// 其他代碼省略
}
<bean id="userService" class="ml.orlion.service.UserService"
init-method="init" destroy-method="destroy">
<property name="userDao" ref="userDao"/>
</bean>
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) appContext.getBean("userService");
appContext.destroy(); // 必須主動調用才會觸發 destroy-method
注意: 若 Bean 的
scope="prototype",調用destroy()不會銷毀 Bean,容器不管理原型 Bean 的完整生命週期。