SpringBean的生命周期
Spring Bean 是什么
Bean 定義本質上是創建一個或多個對象的配方。容器在請求時查看有名稱的Bean的配方,并使用該Bean定義所封裝的配置元數據來創建(或獲取)一個實際對象。
在 Spring 框架中,Bean 是指被 Spring 容器管理或者實例化的對象。Bean 可以是任何一個由 Java 實例,例如數據庫連接、業務邏輯類、控制器等等。Spring Bean 實例的創建和管理是由 Spring 容器負責的,而不是應用程序本身。
Bean 給我們帶來的優勢主要是將對象的創建和管理和業務邏輯分離開,主打一個低耦合,讓程序本身更易于維護和管理,比如在我們的項目中,連接數據庫的創建和管理只需要交給 Spring 容器就行,業務邏輯在 Service層完成,當需要連接另一個數據庫,只需要修改 Spring 的配置文件即可。
Bean 的作用范圍
為什么Bean默認為單例?
- 為了提高性能
適合交給容器進行管理的bean
- 表現層對象
- 業務層對象
- 數據層對象
- 工具對象
不適合交給容器進行管理的bean
- 封裝實體的域對象
實例化 Bean 的方式
構造方法
提供可使用的構造方法
public class BookServiceImpl implements BookService {
public BookServiceImpl() {
System.out.println(" book constructor...");
}
@Override
public void schedule() {
System.out.println("預定了一本書...");
}
}
如果代碼中只有無參構造的話,比如上面代碼,那么里面的無參構造可以省略,Spring 會使用默認的無參構造,但是如果有帶參構造的話,那就要顯式寫出無參構造
xml配置
<bean id="bookService" class="com.springbean.service.impl.BookServiceImpl"/>
如果不提供無參構造方法的話,就會拋出異常:
Caused by: java.lang.NoSuchMethodException: com.springbean.service.impl.BookServiceImpl.<init>()
實例工廠
使用FactoryBean實例化 bean
xml 配置
需要先配置一個工廠 bean
<bean id="bookFactory" class="com.springbean.appFroInstance.BookFacBean"/>
FactoryBean 實例
public class BookFac implements FactoryBean<BookService> {
@Override
public BookService getObject() throws Exception {
return new BookServiceImpl();
}
@Override
public Class<?> getObjectType() {
return BookService.class;
}
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
}
靜態工廠
xml 配置
<bean id="bookFactory" class="com.springbean.factory.StaticBookFactory" factory-method="getBookSchedule"/>
靜態方法
public class StaticBookFactory {
public static BookService getBookSchedule(){
return new BookServiceImpl();
}
}
Bean 的生命周期
概念
bean 的生命周期
簡單來說就是,bean從創建到銷毀的整體過程
bean 的生命周期控制
在 bean創建后到銷毀前做一些事情
生命周期過程
簡要版
初始化容器
- 創建對象(內存分配)
- 執行構造方法
- 執行屬性注入(set)
- 執行
bean初始化方法
使用bean
- 執行業務操作
關閉 / 銷毀容器
- 執行
bean銷毀方法

詳細版
- 實例化:Spring 容器根據配置文件或注解實例化對象
- 屬性注入:Spring 將依賴(通過 setter 或者字段注入)注入到 Bean 實例中
- 初始化前的擴展機制:如果 Bean 實現了
BeanNameAware等 aware 接口,則執行 aware 注入 - 初始化前(BeanPostProcessor):在 Bean 初始化前,可以通過 BeanPostProcessor 接口對 Bean 進行一些額外的處理
- 初始化:調用
InitializingBean接口的afterPropertiesSet()方法或通過init-method屬性指定的方法 - 初始化后(BeanPostProcessor):在 Bean 初始化后,可以通過
BeanPostProcessor進行進一步處理 - 使用Bean:Bean 已經初始化完成,可以被容器中的其他 Bean 使用
- 銷毀:當容器關閉時,Spring 調用 DisposableBean 接口的
destroy()或者通過destroy-method屬性指定的銷毀方法。

代碼模擬
沒添加set方法(屬性注入)
1)xml 配置
<bean id="bookDao" class="com.springbean.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy"/>
2)業務邏輯代碼
編寫接口代碼:
public interface BookDao {
void save();
void init();
void destroy();
}
實現類:
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("book dao save...");
}
@Override
public void init() {
System.out.println("init...");
}
@Override
public void destroy() {
System.out.println("destroy...");
}
}
3)測試代碼:
public class BookMain {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
applicationContext.registerShutdownHook();
BookDao bookDao = (BookDao) applicationContext.getBean("bookDao");
bookDao.save();
// applicationContext.close();
}
}
registerShutdownHook是Spring框架中ConfigurableApplicationContext接口的一個方法,用于注冊一個JVM關閉鉤子
作用:在JVM關閉的時候,確保Spring容器可以優雅關閉,并執行所有單例bean的銷毀回調方法
工作原理
- 注冊鉤子:向 JVM 注冊一個關閉鉤子線程
- JVM 關閉時觸發:當 JVM 收到關閉信號(如 Ctrl+C、系統關閉等)時,會調用這個鉤子
- 關閉 Spring 容器:鉤子線程會調用
ApplicationContext的close()方法 - 執行銷毀回調:Spring 會調用所有單例 bean 的銷毀方法(如
@PreDestroy、DisposableBean接口、destroy-method等)
在虛擬機退出前先關閉容器再退出虛擬機
4)執行結果:
init...
book dao save...
destroy...
添加set
在業務邏輯中添加set方法的bean初始化容器的順序變化
1)先看執行結果的變化
# 創建對象
init...
# 執行構造方法
service constructor...
# 執行屬性注入
service set ...
# 執行 bean 初始化方法
service init...
# 執行業務操作
預定了一本書...
book dao save...
# 關閉銷毀容器
service destroy...
destroy...
2)添加set之后的xml配置
<bean id="bookService" class="com.springbean.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
3)業務邏輯代碼
實現InitializingBean, DisposableBean接口
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
private BookDao bookDao;
public BookServiceImpl() {
System.out.println("service constructor...");
}
@Override
public void schedule() {
System.out.println("預定了一本書...");
bookDao.save();
}
public void setBookDao(BookDao bookDao) {
System.out.println("service set ...");
this.bookDao = bookDao;
}
public void destroy() throws Exception{
System.out.println("service destroy...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("service init...");
}
}
afterPropertiesSet:初始化回調
源碼解釋:
由包含的BeanFactory在設置所有bean屬性并滿足BeanFactoryAware、ApplicationContextAware等條件后調用。該方法允許bean實例在已設置所有bean屬性時對其整體配置和最終初始化進行驗證。
拋出異常: 在出現配置錯誤(例如未能設置一個必要屬性)或由于其他任何原因初始化失敗的情況下
4)測試函數代碼:
public class BookMain {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
applicationContext.registerShutdownHook();
BookDao bookDao = (BookDao) applicationContext.getBean("bookDao");
BookService bookService = (BookService) applicationContext.getBean("bookService");
bookService.schedule();
}
}

浙公網安備 33010602011771號