欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

?Spring?中?Bean?的生命周期詳解

 更新時(shí)間:2022年09月13日 09:38:40   作者:Java中文社群???????  
這篇文章主要介紹了Spring中Bean的生命周期詳解,Java中的公共類(lèi)稱(chēng)之為Bean或Java?Bean,而Spring中的Bean指的是將對(duì)象的生命周期

前言

Java 中的公共類(lèi)稱(chēng)之為 Bean 或 Java Bean,而 Spring 中的 Bean 指的是將對(duì)象的生命周期,交個(gè) Spring IoC 容器來(lái)管理的對(duì)象。所以 Spring 中的 Bean 對(duì)象在使用時(shí),無(wú)需通過(guò) new 來(lái)創(chuàng)建對(duì)象,只需要通過(guò) DI(依賴(lài)注入),從 Spring 中取出要使用的對(duì)象即可。 那么 Spring 中,Bean 的生命周期又有哪些呢?接下來(lái),我們一起來(lái)看。

1.Bean 生命周期

Spring 中 Bean 的生命周期是指:Bean 在 Spring(IoC)中從創(chuàng)建到銷(xiāo)毀的整個(gè)過(guò)程。

 Spring 中 Bean 的生命周期主要包含以下 5 部分:

  • 實(shí)例化:為 Bean 分配內(nèi)存空間;
  • 設(shè)置屬性:將當(dāng)前類(lèi)依賴(lài)的 Bean 屬性,進(jìn)行注入和裝配;
  • 初始化:
    • 執(zhí)行各種通知;
    • 執(zhí)行初始化的前置方法;
    • 執(zhí)行初始化方法;
    • 執(zhí)行初始化的后置方法。
  • 使用 Bean:在程序中使用 Bean 對(duì)象;
  • 銷(xiāo)毀 Bean:將 Bean 對(duì)象進(jìn)行銷(xiāo)毀操作。

以上生命周期中,需要注意的是:“實(shí)例化”和“初始化”是兩個(gè)完全不同的過(guò)程,千萬(wàn)不要搞混,實(shí)例化只是給 Bean 分配了內(nèi)存空間,而初始化則是將程序的執(zhí)行權(quán),從系統(tǒng)級(jí)別轉(zhuǎn)換到用戶(hù)級(jí)別,并開(kāi)始執(zhí)行用戶(hù)添加的業(yè)務(wù)代碼

2.代碼演示

接下來(lái)我們使用代碼的方式在 Spring Boot 中,給大家演示一下 Bean 的生命周期。

PS:因?yàn)?Spring Boot 是基于 Spring 創(chuàng)建的,所以 Bean 在 Spring 或 Spring Boot 中的行為都是一致的,而 Spring Boot 又是目前主流的框架,所以本文使用 Spring Boot 來(lái)演示 Bean 的生命周期。

首先,我們創(chuàng)建一個(gè) Bean 對(duì)象,起名為 BeanLifeComponent(類(lèi)命無(wú)所謂,可隨意指定),它的具體實(shí)現(xiàn)代碼如下:

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
public class BeanLifeComponent implements BeanNameAware {
    public void setBeanName(String s) {
        System.out.println("執(zhí)行 BeanName 的通知方法");
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("執(zhí)行初始化方法");
    }

    public void use() {
        System.out.println("使用 Bean");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("執(zhí)行銷(xiāo)毀方法");
    }
}

然后,我們?cè)賱?chuàng)建一個(gè) MyBeanPostProcessor 類(lèi)(類(lèi)命無(wú)所謂,可隨意指定),來(lái)實(shí)現(xiàn)初始化的前置方法和初始化的后置方法,

具體實(shí)現(xiàn)代碼如下:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("beanLifeComponent")) {
            System.out.println("執(zhí)行初始化前置方法");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("beanLifeComponent")) {
            System.out.println("執(zhí)行初始化后置方法");
        }
        return bean;
    }
}

為什么要?jiǎng)?chuàng)建一個(gè)單獨(dú)的類(lèi)來(lái)執(zhí)行初始化的前置方法和初始化的后置方法呢? 這是因?yàn)槌跏蓟那爸梅椒ê秃笾梅椒ㄊ菫樗?Bean 服務(wù)的,而非為某一個(gè) Bean 服務(wù)的,所以這兩個(gè)方法不能寫(xiě)在某個(gè)具體的 Bean 中,否則(這兩個(gè)方法)不會(huì)執(zhí)行。 最后,在 Spring Boot 的啟動(dòng)類(lèi)中獲取 Bean,

具體實(shí)現(xiàn)代碼如下:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        // 得到上下文對(duì)象,并啟動(dòng) Spring Boot 項(xiàng)目
        ConfigurableApplicationContext context = 
            SpringApplication.run(DemoApplication.class, args);
        // 獲取 Bean
        BeanLifeComponent component = context.getBean(BeanLifeComponent.class);
        // 使用 Bean
        component.use();
        // 停止 Spring Boot 項(xiàng)目
        context.close();
    }
}

以上程序最終的執(zhí)行結(jié)果如下圖所示: 

 從上面的執(zhí)行結(jié)果可以看出,代碼執(zhí)行順序符合 Bean 生命周期的執(zhí)行順序:

  • 實(shí)例化:為 Bean 分配內(nèi)存空間;
  • 設(shè)置屬性:將當(dāng)前類(lèi)依賴(lài)的 Bean 屬性,進(jìn)行注入和裝配;
  • 初始化:
    • 執(zhí)行各種通知;
    • 執(zhí)行初始化的前置方法;
    • 執(zhí)行初始化方法;
    • 執(zhí)行初始化的后置方法。
  • 使用 Bean:在程序中使用 Bean 對(duì)象;
  • 銷(xiāo)毀 Bean:將 Bean 對(duì)象進(jìn)行銷(xiāo)毀操作。

那么問(wèn)題來(lái)了,能不能先執(zhí)行初始化再執(zhí)行設(shè)置屬性呢?也就是將生命周期中的步驟 2 和步驟 3 的執(zhí)行順序交換一下? 答案是否定的。想象一個(gè)場(chǎng)景,如果在初始化方法中要用到被注入對(duì)象的某個(gè)方法,

比如以下代碼:

@Controller
public class UserController {
    @Resource
    private UserService userService;

    @PostConstruct // 初始化方法
    public void postConstruct() {
        userService.sayHi();
    }
}

此時(shí)如果先執(zhí)行步驟 2,先將 UserService 注入到當(dāng)前類(lèi),再調(diào)用步驟 3 執(zhí)行初始化,那么程序的執(zhí)行是正常的。然而如果將交互步驟 2 和步驟 3 的執(zhí)行順序,那么程序執(zhí)行就會(huì)報(bào)錯(cuò)(空指針異常),所以 Bean 的生命周期的順序必須是:

1.實(shí)例化:為 Bean 分配內(nèi)存空間; 2.設(shè)置屬性:將當(dāng)前類(lèi)依賴(lài)的 Bean 屬性,進(jìn)行注入和裝配; 3.初始化:

  • 執(zhí)行各種通知;
  • 執(zhí)行初始化的前置方法;
  • 執(zhí)行初始化方法;
  • 執(zhí)行初始化的后置方法。 4.使用 Bean:在程序中使用 Bean 對(duì)象; 5.銷(xiāo)毀 Bean:將 Bean 對(duì)象進(jìn)行銷(xiāo)毀操作。

總結(jié)

Bean 的生命周期指的是 Bean 在 Spring(IoC)中從創(chuàng)建到銷(xiāo)毀的整個(gè)過(guò)程。Bean 的生命周期主要包含以下 5 個(gè)流程:

1.實(shí)例化:為 Bean 分配內(nèi)存空間;

2.設(shè)置屬性:將當(dāng)前類(lèi)依賴(lài)的 Bean 屬性,進(jìn)行注入和裝配;

3.初始化:

  • 執(zhí)行各種通知;
  • 執(zhí)行初始化的前置方法;
  • 執(zhí)行初始化方法;
  • 執(zhí)行初始化的后置方法。 4.使用 Bean:在程序中使用 Bean 對(duì)象; 5.銷(xiāo)毀 Bean:將 Bean 對(duì)象進(jìn)行銷(xiāo)毀操作。

到此這篇關(guān)于 Spring 中 Bean 的生命周期詳解的文章就介紹到這了,更多相關(guān) Spring Bean 生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MyBatis-Plus的yml配置方式小結(jié)

    MyBatis-Plus的yml配置方式小結(jié)

    本文主要介紹了MyBatis-Plus的yml配置方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-11-11
  • 源碼解析Java類(lèi)加載器

    源碼解析Java類(lèi)加載器

    這篇文章主要給大家介紹了Java類(lèi)加載器源碼解析的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java使用Catcher捕獲異常的實(shí)現(xiàn)

    Java使用Catcher捕獲異常的實(shí)現(xiàn)

    本文主要介紹了Java使用Catcher捕獲異常的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 圖解Java經(jīng)典算法快速排序的原理與實(shí)現(xiàn)

    圖解Java經(jīng)典算法快速排序的原理與實(shí)現(xiàn)

    快速排序是基于二分的思想,對(duì)冒泡排序的一種改進(jìn)。主要思想是確立一個(gè)基數(shù),將小于基數(shù)的數(shù)放到基數(shù)左邊,大于基數(shù)的數(shù)字放到基數(shù)的右邊,然后在對(duì)這兩部分進(jìn)一步排序,從而實(shí)現(xiàn)對(duì)數(shù)組的排序
    2022-09-09
  • Java8優(yōu)雅的字符串拼接工具類(lèi)StringJoiner實(shí)例代碼

    Java8優(yōu)雅的字符串拼接工具類(lèi)StringJoiner實(shí)例代碼

    這篇文章主要給大家介紹了關(guān)于Java8優(yōu)雅的字符串拼接工具類(lèi)StringJoiner的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 基于Java并發(fā)容器ConcurrentHashMap#put方法解析

    基于Java并發(fā)容器ConcurrentHashMap#put方法解析

    下面小編就為大家?guī)?lái)一篇基于Java并發(fā)容器ConcurrentHashMap#put方法解析。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • Spring Security架構(gòu)以及源碼詳析

    Spring Security架構(gòu)以及源碼詳析

    這篇文章主要給大家介紹了關(guān)于Spring Security架構(gòu)以及源碼的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06
  • SpringBoot配置https實(shí)操方法

    SpringBoot配置https實(shí)操方法

    在本篇文章里小編給大家整理的是關(guān)于SpringBoot配置https實(shí)操方法以及相關(guān)知識(shí)點(diǎn),需要的朋友們參考下。
    2019-11-11
  • SpringBoot如何從配置文件中讀取配置參數(shù)

    SpringBoot如何從配置文件中讀取配置參數(shù)

    這篇文章主要介紹了SpringBoot如何從配置文件中讀取配置參數(shù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Springboot使用maven打包指定mainClass問(wèn)題

    Springboot使用maven打包指定mainClass問(wèn)題

    這篇文章主要介紹了Springboot使用maven打包指定mainClass問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04

最新評(píng)論