首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring 容器 Bean 初始化全流程:單例、原型、懶加載與生命週期

     編輯:Java 相關知識

Spring 容器管理 Bean 的創建、配置、初始化與銷毀,理解其作用域與初始化時機是正確使用框架的前提。本文系統講解singleton/prototype作用域差異、lazy-init懶加載機制、初始化回調方法、BeanPostProcessor擴展點,並給出驗證代碼。

一、Bean 作用域

配置示例

<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" />

三、初始化與銷毀回調

  1. JSR-250 註解(推薦):@PostConstruct、@PreDestroy
  2. 接口回調:實現 InitializingBean.afterPropertiesSet()、DisposableBean.destroy()
  3. 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 生命週期
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
作用域說明創建時機適用場景
singleton(默認)容器中僅一個實例容器啟動時(預實例化)無狀態服務、DAO、工具類
prototype每次獲取創建新實例getBean() 調用時有狀態對象、請求級組件
request每個 HTTP 請求一個實例請求到達時Web 控制器、表單對象
session每個 HTTP Session 一個實例Session 創建時用戶偏好、購物車