| 作用域 | 說明 | 創建時機 | 適用場景 |
| singleton(默認) | 容器中僅一個實例 | 容器啟動時(預實例化) | 無狀態服務、DAO、工具類 |
| prototype | 每次獲取創建新實例 | getBean() 調用時 | 有狀態對象、請求級組件 |
| request | 每個 HTTP 請求一個實例 | 請求到達時 | Web 控制器、表單對象 |
| session | 每個 HTTP Session 一個實例 | Session 創建時 | 用戶偏好、購物車 |
配置示例
<bean id="people" class="com.example.People" scope="prototype" />
<!-- 或註解 -->
@Component
@Scope("prototype")
public class People { ... }
二、懶加載:lazy-init
lazy-init="true":首次 getBean() 時創建(僅對 singleton 有效)
lazy-init="false/default":容器啟動時預創建
- 全局默認:
<beans default-lazy-init="true">
<bean id="heavyService" class="com.example.HeavyService" lazy-init="true" />
三、初始化與銷毀回調
- JSR-250 註解(推薦):
@PostConstruct、@PreDestroy
- 接口回調:實現
InitializingBean.afterPropertiesSet()、DisposableBean.destroy()
- XML 配置:
init-method="init"、destroy-method="cleanup"
public class MyBean {
@PostConstruct
public void init() { System.out.println("Bean 初始化"); }
@PreDestroy
public void cleanup() { System.out.println("Bean 銷毀"); }
}
四、驗證代碼
public class SpringLifecycleDemo {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
// 1. 驗證 singleton
People p1 = ctx.getBean("people", People.class);
People p2 = ctx.getBean("people", People.class);
System.out.println("singleton 同一實例? " + (p1 == p2)); // true
// 2. 驗證 prototype
ctx.getBeanFactory().registerSingleton("prototypePeople", new People()); // 手動註冊原型
People p3 = ctx.getBean("prototypePeople", People.class);
People p4 = ctx.getBean("prototypePeople", People.class);
System.out.println("prototype 同一實例? " + (p3 == p4)); // false
// 3. 關閉容器觸發銷毀
((ConfigurableApplicationContext) ctx).close();
}
}
五、BeanPostProcessor:擴展初始化流程
實現 BeanPostProcessor 可在 Bean 初始化前後攔截:
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println("初始化前: " + beanName);
return bean; // 可返回代理對象
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println("初始化後: " + beanName);
return bean;
}
}
應用場景:AOP 代理創建、註解掃描、屬性加密解密、驗證必填字段。
六、總結
- 默認 singleton + 預實例化:啟動慢、運行快、線程安全需自行保證
- prototype:每次新建、不走銷毀回調、慎用於高頻場景
- lazy-init:解決啟動慢、循環依賴,但首次調用有延遲
- @PostConstruct/@PreDestroy:標準、非侵入、首選方式
- BeanPostProcessor:框架擴展核心,掌握它掌握 Spring 生命週期
- 上一篇文章: Java 精準提取網頁發布時間:多模式正則匹配與格式標準化
- 下一篇文章: Java 多線程大文件分割:RandomAccessFile + CountDownLatch 秒級處理 GB 級 CSV
Copyright ©
程式碼之家 All Rights Reserved