深入理解Spring Boot Bean生命周期

Spring Boot是一種基於Spring框架的快速應用程序開發工具,它旨在使Spring應用程序的開發變得更簡單、更快速,但對於新手來說可能仍然是一種挑戰,尤其是對於生命周期背後的實現細節。本文將從多個方面詳細闡述Spring Boot的Bean生命周期,幫助開發者更好地理解和使用Spring Boot。

一、Bean的實例化

當Bean被加載到容器中時,需要根據配置信息創建Bean的實例對象,這個過程叫做Bean的實例化。Spring提供了兩種方式來創建Bean的實例:

  1. 使用默認構造函數:Spring通過無參構造函數來創建Bean實例,這需要保證該Bean類中存在無參構造函數。
  2. 工廠方法:對於需要進行一些初始化或者創建的邏輯處理的Bean,Spring也提供了工廠方法。Developer可以在Bean類中編寫返回對象的靜態方法,由Spring容器調用所返回的實例。

下面是使用默認構造函數和工廠方法分別實例化Bean的實現示例:

public class User {
    private String name;
    private int age;
    
    // 默認構造函數
    public User() {}

    // 帶參數的構造函數
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 工廠方法
    public static User createUser() {
        return new User("Tom", 25);
    }

    // getter和setter方法省略
}

@Configuration
public class AppConfig {

    // 通過@Bean註解,將User作為一個Bean注入到Spring容器中
    @Bean(name = "user")
    public User initUserByDefaultConstructor() {
        return new User();
    }

    @Bean(name = "user2")
    public User initUserByStaticFactoryMethod() {
        return User.createUser();
    }
}

二、Bean的初始化

當Bean實例創建成功後,需要對該實例執行一些初始化的工作。Spring提供了兩個接口來支持Bean初始化:

  1. InitializingBean:該接口提供了一個afterPropertiesSet()方法,該方法在Bean實例化完成後回調。InitializingBean接口可以讓開發者在Bean實例化完成後進行一些初始化的操作。
  2. 配置init方法:開發者可以在Bean類中配置init方法,該方法將在Bean實例化完成後被容器調用。開發者應該考慮使用init方法進行一些初始化的操作,這樣更加靈活。

下面是使用InitializingBean接口和配置init方法分別實例化Bean的實現示例:

public class User implements InitializingBean {
    private String name;
    private int age;

    public User() {}

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static User createUser() {
        return new User("Tom", 25);
    }

    public void afterPropertiesSet() {
        System.out.println("--------------Bean初始化完成-------------");
    }

    public void initMethod() {
        System.out.println("-------------通過initMethod()方法初始化Bean----------------");
    }

    // getter和setter方法省略
}

@Configuration
public class AppConfig {

    @Bean(name = "user")
    public User initUserByDefaultConstructor() {
        User user = new User();
        return user;
    }

    @Bean(name = "user2")
    public User initUserByStaticFactoryMethod() {
        User user = User.createUser();
        return user;
    }

    @Bean(name = "user3", initMethod = "initMethod")
    public User initUserByInitMethod() {
        User user = new User("Tom", 25);
        return user;
    }
}

三、Bean的依賴注入

依賴注入是Spring框架的核心特性之一。依賴注入的目的是將Bean之間的依賴關係從程序代碼中解耦出來,讓開發者可以更加靈活的編寫程序。

Spring支持三種方式進行依賴注入:

  1. 構造函數依賴注入:通過Bean類中的構造函數實現依賴注入。
  2. 屬性Setter方法依賴注入:通過Bean類中的setProperty()方法實現依賴注入。
  3. 註解依賴注入:通過註解方式自動裝配實現依賴注入。

下面是三種方式實現依賴注入的示例:

public class User {
    private String name;
    private int age;

    public User() {}

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void initMethod() {
        System.out.println("----------------依賴注入完成-----------");
    }

    // getter和setter方法
}

public class ProductService {
    private User user;

    public ProductService(User user) {
        this.user = user;
    }

    public void validate() {
        System.out.println("User's Name:" + user.getName() + " User's Age:" + user.getAge());
    }
}

@Configuration
public class AppConfig {

    @Bean(name = "user")
    public User initUser() {
        User user = new User("Tom", 25);
        return user;
    }

    /**
     * 構造方法注入
     * @param user
     * @return
     */
    @Bean(name = "productService")
    public ProductService initProductServiceByConstructor(User user) {
        return new ProductService(user);
    }

    /**
     * setter方法注入
     * @param user
     * @return
     */
    @Bean(name = "productService2")
    public ProductService initProductServiceBySetMethod(User user) {
        ProductService productService = new ProductService();
        productService.setUser(user);
        return productService;
    }

    /**
     * 註解注入
     * @return
     */
    @Bean(name = "productService3")
    public ProductService initProductService() {
        return new ProductService(new User("Tomson", 26));
    }
}

四、Bean的銷毀

在Bean實例不再需要,容器需要將其從容器中清除前,需要執行銷毀Bean的相關操作。Spring提供了兩個方法來支持Bean的銷毀操作:

  1. DisposableBean:該接口提供了一個destroy()方法,該方法在Bean銷毀之前將被調用。
  2. 配置destroy方法:在Bean類中可以配置destroy方法,該方法將在Bean銷毀之前被調用。

下面是DisposableBean方法和配置destroy方法分別實現Bean銷毀操作的示例:

public class User implements InitializingBean, DisposableBean {
    private String name;
    private int age;

    public User() {}

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void setProperty(String name, int age){
        this.name = name;
        this.age = age;
    }

    public void afterPropertiesSet() {
        System.out.println("--------------Bean初始化完成-------------");
    }

    public void initMethod() {
        System.out.println("-------------通過init-method()方法初始化Bean----------------");
    }

    public void destroy() throws Exception {
        System.out.println("--------------銷毀Bean-------------");
    }

    public void destroyMethod() {
        System.out.println("----------------通過destroy-method()方法銷毀Bean-----------");
    }

    // getter、setter方法
}

@Configuration
public class AppConfig {

    @Bean(name = "user", initMethod = "initMethod", destroyMethod = "destroyMethod")
    public User initUser() {
        User user = new User();
        user.setProperty("Tom", 25);
        return user;
    }

    /**
     * 通過DisposableBean實現銷毀操作
     * @return
     */
    @Bean(name = "user2")
    public User initUser2() {
        User user = new User();
        user.setProperty("Tomson", 26);
        return user;
    }

    @Bean(name = "productService2")
    public ProductService initProductServiceBySetMethod(User user) {
        ProductService productService = new ProductService();
        productService.setUser(user);
        return productService;
    }
}

五、小結

通過以上介紹,我們可以看到Spring Boot Bean的生命周期包括了Bean實例化、Bean初始化、依賴注入以及Bean銷毀這四個方面。Spring Boot提供了多種方式來支持Bean生命周期的控制,在使用的時候,開發者應該根據實際需求選擇合適的方式,並按照Spring Boot的規則來編寫代碼。

原創文章,作者:JNLVR,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/371259.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
JNLVR的頭像JNLVR
上一篇 2025-04-23 00:48
下一篇 2025-04-23 00:48

相關推薦

發表回復

登錄後才能評論