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

Spring中Bean的生命周期及實(shí)例化操作詳解

 更新時(shí)間:2023年08月17日 09:33:34   投稿:caobin  
這篇文章主要介紹了Spring中Bean的生命周期及實(shí)例化操作詳解,spring的核心思想之一IOC就是通過(guò)IOC容器對(duì)Bean的創(chuàng)建和各個(gè)bean之間的依賴(lài)關(guān)系進(jìn)行操作,今天就來(lái)和大家分享一下bean的生命周期相關(guān)知識(shí)點(diǎn),需要的朋友可以參考下

前言

Bean的生命周期分為實(shí)例化Instantiation 、屬性賦值Populate 、初始化Initalization 、銷(xiāo)毀Destruction,下面我將從這四個(gè)方面深入分享Bean的生命周期。

一、Bean的介紹

我們首先來(lái)看看spring的兩大核心思想IOC(控制反轉(zhuǎn)),DI(依賴(lài)注入)和AOP (面向切面編程)

  • IOC(控制反轉(zhuǎn)):是Spring框架的核心思想之一, 主要用于解耦。I0C是指將創(chuàng)建對(duì)象的控制權(quán)轉(zhuǎn)移給Spring框架進(jìn)行管理。由Spring框架根據(jù)配置文件或注解等元數(shù)據(jù),創(chuàng)建bean對(duì)象并管理各個(gè)bean對(duì)象之間的依賴(lài)關(guān)系。使對(duì)象之間形成松散耦合的關(guān)系,利于解耦。
  • DI(依賴(lài)注入):是對(duì)IOC概念的不同角度的描述,是指應(yīng)用程序在運(yùn)行時(shí),每一個(gè)bean對(duì)象都依賴(lài)IOC容器注入當(dāng)前bean對(duì)象所需要的另外一-個(gè)bean對(duì)象。 (例如在MyBatis整合Spring時(shí), SqISessionFactoryBean 依賴(lài)容器注入-個(gè)DataSource數(shù)據(jù)源) 
  • IOC容器:IOC容器屬于Spring Core模塊,是用來(lái)創(chuàng)建和管理Bean的地方,以默認(rèn)單例的方式將bean存儲(chǔ)在以ConcurrentHashMap的形式存儲(chǔ)了BeanDefinition 對(duì)象,該對(duì)象封裝了Spring 對(duì)一個(gè)Bean所有信息的定義,包括類(lèi)名,屬性,構(gòu)造方法參數(shù),依賴(lài),是否延遲加載,是否單例等,之后對(duì)Bean的操作都是直接對(duì)它進(jìn)行的。 IOC容器的初始化分三個(gè)步驟:
    • BeanDefinition的資源定位
    • BeanDefinition的資源的載入和解析
    • BeanDefinition的注冊(cè) 
  • AOP (面向切面編程):Spring AOP基于動(dòng)態(tài)代理實(shí)現(xiàn)。 能夠?qū)⒛切┡c業(yè)務(wù)無(wú)關(guān), 卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯(例如事務(wù)處理、日志管理、權(quán)限控制等)封裝抽取成一個(gè)可重用的模塊, 這個(gè)模塊被命名為“ 切面”(Aspect) ,便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,并有利于未來(lái)的可拓展性和可維護(hù)性;

什么是Bean:

bean是計(jì)算機(jī)自動(dòng)生成的類(lèi),bean是一個(gè)由Spring IoC容器實(shí)例化、組裝和管理的對(duì)象。

也就是說(shuō),bean并不是程序員編輯的,而是程序運(yùn)行時(shí),由spring通過(guò)反射生成的

Bean的生命周期:

實(shí)例化->屬性賦值->初始化->銷(xiāo)毀 

Bean的作用域: 

  • singleton : 唯一 bean 實(shí)例,Spring 中的 bean 默認(rèn)都是單例的。
  • prototype : 每次請(qǐng)求都會(huì)創(chuàng)建一個(gè)新的 bean 實(shí)例。
  • request : 每一次 HTTP 請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的 bean,該 bean 僅在當(dāng)前 HTTP request 內(nèi)有效。
  • session : 每一次 HTTP 請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的 bean,該 bean 僅在當(dāng)前 HTTP session 內(nèi)有效。
  • global-session: 全局 session 作用域,僅僅在基于 Portlet 的 web 應(yīng)用中才有意義,Spring5 已經(jīng)沒(méi)有了。Portlet 是能夠生成語(yǔ)義代碼

(例如:HTML)片段的小型 Java Web 插件。它們基于 portlet 容器,可以像 servlet 一樣處理 HTTP 請(qǐng)求。

但是,與 servlet 不同,每個(gè) portlet 都有不同的會(huì)話。  

二、詳細(xì)過(guò)程

實(shí)例化和屬性賦值分別對(duì)應(yīng)構(gòu)造方法和setter方法的注入,初始化和銷(xiāo)毀是用戶(hù)能自定義擴(kuò)展的兩個(gè)階段。

可通過(guò)查源碼的方式發(fā)現(xiàn),他們都在doCreate()方法中,如下:

可通過(guò)查源碼的方式發(fā)現(xiàn),他們都在doCreate()方法中,

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {
   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (instanceWrapper == null) {
       // 實(shí)例化階段!
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
       // 屬性賦值階段!
      populateBean(beanName, mbd, instanceWrapper);
       // 初始化階段!
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
}

1. Bean的實(shí)例化

Spring對(duì)Bean進(jìn)行實(shí)例化(相當(dāng)于 new XXX())

對(duì)于 BeanFactory 一般是延遲實(shí)例化,就是說(shuō)調(diào)用 getBean 方法才會(huì)實(shí)例化

但是對(duì)于 ApplicationContext ,當(dāng)容器初始化完成之后,就完成了所有Bean的實(shí)例化工作。

實(shí)例化的對(duì)象被包裝在 BeanWrapper 對(duì)象中, BeanWrapper 提供了設(shè)置對(duì)象屬性的接口,從而避免了使用反射機(jī)制設(shè)置屬性。

2. InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor 這個(gè)接口主要是幫助你在Bean實(shí)例化之前做一些操作。

它繼承自 BeanPostProcessor 接口,其中 postProcessBeforeInstantiation() 方法是在目標(biāo)對(duì)象實(shí)例化之前調(diào)用的方法,可以返回目標(biāo)實(shí)例的一個(gè)代理用來(lái)代替目標(biāo)實(shí)例。

postProcessPropertyValues 方法是在屬性值被設(shè)置到目標(biāo)實(shí)例之前調(diào)用,可以修改屬性的設(shè)值。

3. 設(shè)置屬性(依賴(lài)注入)

實(shí)例化后的對(duì)象被封裝到 BeanWrapper 對(duì)象中,并且此時(shí)對(duì)象是一個(gè)原生狀態(tài),并沒(méi)有執(zhí)行依賴(lài)注入。

緊接著,Spring根據(jù) BeanDefinition 中的信息進(jìn)行依賴(lài)注入。

并且通過(guò) BeanWrapper 提供的設(shè)置屬性的接口完成依賴(lài)注入。

4. 注入Aware接口

Spring 會(huì)檢測(cè)該對(duì)象是否實(shí)現(xiàn)了xxxAware接口,并將相關(guān)的xxxAware實(shí)例注入給Bean。

各種各樣的Aware接口,其作用就是在對(duì)象實(shí)例化完成后將Aware接口定義中規(guī)定的依賴(lài)注入到當(dāng)前實(shí)例中。

比較常見(jiàn)的 ApplicationContextAware 接口,實(shí)現(xiàn)了這個(gè)接口的類(lèi)都可以獲取到一個(gè) ApplicationContext 對(duì)象,當(dāng)容器中每個(gè)對(duì)象的實(shí)例化過(guò)程走到 BeanPostProcessor 前置處理這一步時(shí),容器會(huì)檢測(cè)到之前注冊(cè)到容器的 ApplicationContextAwareProcessor ,然后就會(huì)調(diào)用其 postProcessorBeforeInitialization() 方法,檢查并設(shè)置Aware相關(guān)的依賴(lài)。

5. BeanPostProcessor的postProcessBeforeInitialzation方法

經(jīng)過(guò)上述步驟后,Bean對(duì)象已經(jīng)被正確構(gòu)造了,如果你想要對(duì)象被使用之前在進(jìn)行自定義的處理,可以通過(guò) BeanPostProcessor 接口實(shí)現(xiàn)。

該接口提供了兩個(gè)方法

其中 postProcessBeforeInitialzation(Objectbean,StringbeanName) 方法;

當(dāng)前正在初始化的bean對(duì)象會(huì)被傳遞進(jìn)來(lái),我們就可以對(duì)這個(gè)Bean做任何處理,這個(gè)方法會(huì)先于 InitializingBean 執(zhí)行,因此稱(chēng)為前置處理。

6. InitializingBean與init-method

如果Bean實(shí)現(xiàn)了 InitializingBean 接口,Spring將調(diào)用它們的 afterPropertiesSet 方法,作用與在配置文件中對(duì)Bean使用 init-method 聲明初始化的作用一樣,都是在Bean的全部屬性設(shè)置成功后執(zhí)行的初始化方法。

afterPropertiesSet 方法與前置處理不同的是,由于其沒(méi)有把Bean對(duì)象傳進(jìn)來(lái),因此在這一步?jīng)]有辦法處理對(duì)象本身,只能增加一些額外的邏輯。

7.BeanPostProcess的postProcessAfterInitialzation方法

BeanPostProcess 的 postProcessAfterInitialzation(Objectbean,StringbeanName) 方法;當(dāng)前正在初始化的bean對(duì)象會(huì)被傳遞進(jìn)來(lái),我們就可以對(duì)這個(gè)bean做任何處理。

這個(gè)函數(shù)會(huì)在 InitializingBean 完成后執(zhí)行,因此稱(chēng)為后置處理。

8. Bean初始化結(jié)束

經(jīng)過(guò)以上的工作以后,Bean的初始化就結(jié)束了,Bean將一直駐留在應(yīng)用上下文中給應(yīng)用使用,知道應(yīng)用上下文被銷(xiāo)毀。

9. DispostbleBean接口

如果Bean實(shí)現(xiàn)了 DispostbleBean 接口,Spring將調(diào)用它的 destroy 方法,作用與在配置文件中對(duì)Bean使用 destroy-method 屬性的作用是一樣的,都是在Bean實(shí)例銷(xiāo)毀前執(zhí)行的方法。

最后的最后用我多年畫(huà)工附一張如給大家康康:

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

相關(guān)文章

  • hibernate和mybatis對(duì)比分析

    hibernate和mybatis對(duì)比分析

    通過(guò)本文給分享了hibernate和mybatis對(duì)比分析,從開(kāi)發(fā)對(duì)比,系統(tǒng)調(diào)優(yōu)對(duì)比,對(duì)象管理與抓取策略,緩存機(jī)制對(duì)比等方面給大家詳細(xì)介紹,需要的朋友參考下吧
    2017-09-09
  • IDEA 2020.1打開(kāi)時(shí)閃退的問(wèn)題及解決方法(完美解決方法)

    IDEA 2020.1打開(kāi)時(shí)閃退的問(wèn)題及解決方法(完美解決方法)

    這篇文章主要介紹了IDEA 2020.1打開(kāi)時(shí)閃退問(wèn)題及解決方法,本文給大家分享我的處理方案,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 關(guān)于IDEA關(guān)聯(lián)數(shù)據(jù)庫(kù)的問(wèn)題

    關(guān)于IDEA關(guān)聯(lián)數(shù)據(jù)庫(kù)的問(wèn)題

    這篇文章主要介紹了IDEA關(guān)聯(lián)數(shù)據(jù)庫(kù)的相關(guān)知識(shí),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • Spring Boot 中常用的注解@RequestParam及基本用法

    Spring Boot 中常用的注解@RequestParam及基本用法

    @RequestParam 是 Spring Framework 和 Spring Boot 中常用的注解之一,用于從請(qǐng)求中獲取參數(shù)值,本文給大家介紹Spring Boot 中常用的注解@RequestParam,感興趣的朋友一起看看吧
    2023-10-10
  • ServletContext中常用方法介紹

    ServletContext中常用方法介紹

    本篇文章是對(duì)ServletContext中的常用方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07
  • 詳解Lombok的坑

    詳解Lombok的坑

    這篇文章主要介紹了詳解Lombok的坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Kotlin與Java的主客觀對(duì)比分析

    Kotlin與Java的主客觀對(duì)比分析

    這篇文章主要介紹了Kotlin與Java的主客觀對(duì)比分析,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • spring boot application properties配置實(shí)例代碼詳解

    spring boot application properties配置實(shí)例代碼詳解

    本文通過(guò)代碼給大家介紹了spring boot application properties配置方法,需要的的朋友參考下吧
    2017-07-07
  • JVM中的程序計(jì)數(shù)寄存器PC是什么詳解

    JVM中的程序計(jì)數(shù)寄存器PC是什么詳解

    這篇文章主要介紹了JVM中的程序計(jì)數(shù)寄存器PC原理分析,JVM中的程序計(jì)數(shù)寄存器(Program Counter Register),Register的命名源于CPU的寄存器,寄存器存儲(chǔ)指令相關(guān)的現(xiàn)場(chǎng)信息
    2021-09-09
  • 詳解如何全注解方式構(gòu)建SpringMVC項(xiàng)目

    詳解如何全注解方式構(gòu)建SpringMVC項(xiàng)目

    這篇文章主要介紹了詳解如何全注解方式構(gòu)建SpringMVC項(xiàng)目,利用Eclipse構(gòu)建SpringMVC項(xiàng)目,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2018-10-10

最新評(píng)論