最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring IOC中的Bean對象用法

 更新時間:2021年09月13日 15:18:45   作者:.SOLO.  
這篇文章主要介紹了Spring IOC中的Bean對象用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Spring IOC中的Bean對象

一、Bean是什么

突然發(fā)現(xiàn)提到了好多次Bean,居然忘記了講Bean是什么。沒事,現(xiàn)在講也不晚。Java中的Bean是一種規(guī)范,是一種特殊的java類。所以我們先來看看Bean的規(guī)范。

  • Bean必須生成public class類。
  • 所有屬性必須封裝,Bean類的屬性都為private。
  • 屬性值應該通過一組方法(getXxx 和 setXxx)來訪問和修改。
  • Bean類必須有一個空的構造函數(shù)(默認構造函數(shù))。

這些就是Bean的基本規(guī)范,我們可以進行擴充,但是這些最基本的都是要滿足的,否則就算不上一個標準的Bean。下面我來舉一個標準的Bean的例子,注意上面的四個要素。

public class User {
    private String id;
    private String name;
    public User(){}
    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

是的,Bean就是這樣的一種特殊的類,這個東西必須要牢記,因為后面會經(jīng)常用到。

二、Bean對象的三種構造方式

自從有了spring之后,對象的構造不用我們再去操心了,一切交給spring完成就行。但是,框架再高級,他的底層依舊是在做一些很簡單的事,這些事可能我們過去也經(jīng)常自己來做。因此,學習spring我們既要知其然也要知其所以然,下面我們就來看看有哪些構造Bean對象的方式。順便了解一下他們的原理是什么。

1. 構造方法構造

這是我們用的最多的一種構造方式。你肯定很好奇,在以前的案例中,為啥我們在配置文件里面寫一句:

<bean id="circle" class="com.demo.Circle"/>

然后這個Bean對象就被spring構造出來放入IOC容器中了?其實這東西沒啥高大上的,實際上就是spring利用反射調用了這個類的默認構造方法而已。就是這么簡單。

那么問題來了,如果我們對象中有屬性(暫時假定屬性只包含基本類型和String,對象屬性會在后面講),我們又該怎么來構造呢?這個配置文件應該怎么去寫呢?很簡單,每個Bean對象中都由setter方法(不記得的可以去復習一下上面寫的的Bean的結構),框架可以通過調用setter方法,把需要的值傳遞給屬性,這就是屬性注入。比如我們試著構造一個本文開頭提到了一個Bean的對象:

<bean id="user" class="com.beans.User">
	<property name="id" value="666"></property>
    <property name="name" value="666"></property>
</bean>

這段配置主要干了什么事呢?首先,就像往常一樣,調用默認構造方法,構造出一個對象,然后調用兩個setter方法,分別給兩個屬性賦值。用傳統(tǒng)代碼表示就是這樣:

User user = new User();
user.setId("666");
user.setName("666");

當然,平時我們自己很少這么做,如果需要給屬性賦值,我們可以直接重載構造方法,通過傳參的方式在創(chuàng)建對象的同時直接給屬性賦值,這樣可以減少代碼量。下面我們來看看怎樣讓框架調用Bean的有參構造方法:

<bean id="user" class="com.beans.User" >
	<constructor-arg name="id" value="666"></constructor-arg>
    <constructor-arg name="name" value="666"></constructor-arg>
</bean>

這段配置就相當于是直接對有參構造方法進行調用,這里的arg是arguement(參數(shù))的縮寫,所以constructor-arg就是構造方法的參數(shù)列表的意思,name很顯然就是參數(shù)名了,value就是我們要填入的參數(shù)值。所以我們就要為參數(shù)列表中所有的參數(shù)進行填值,就像我們過去做的一樣:

User user = new User("666", "666");

現(xiàn)在你應該已經(jīng)了解了spring框架究竟干了什么了吧??此聘叽笊系目蚣茏龅氖乱膊贿^如此嘛,最基本的東西是永遠逃不掉的。

2. 靜態(tài)工廠構造

這種方式一般只有特定場景會使用,所以我們就簡單看看就行。這里的靜態(tài)工廠和我們前面講的工廠模式差不多,首先我們要有一個工廠:

public class UserFactory {
    public static User createPerson(){
        return new User();
    }
    public static User createPerson(Integer id,String name){
        return new User(id,name);
    }
}

下面我們來看看配置文件如何書寫:

<bean id="user" class="com.beans.factory.UserFactory" factory-method="createPerson">
    <constructor-arg name="id" value="666"></constructor-arg>
    <constructor-arg name="name" value="666"></constructor-arg>
</bean>

使用靜態(tài)工廠方法創(chuàng)建Bean實例需要為<bean />元素指定除id外如下屬性:

  • class:指定靜態(tài)工廠的全類名(相當于指定工廠的地址)
  • factory-method:指定由靜態(tài)工廠的哪個方法創(chuàng)建該Bean實例(指定由工廠的哪個車間創(chuàng)建Bean)
  • 方法參數(shù):如果靜態(tài)工廠方法需要參數(shù),則使用<constructor-arg />元素傳入。

3. 實例工廠構造

實例工廠和靜態(tài)工廠唯一的區(qū)別就是我們需要先實例化工廠對象,才能構造我們需要的Bean對象:

<!-- 先構造工廠對象,class指定該工廠的實現(xiàn)類,工廠對象負責產(chǎn)生其他Bean實例 --> 
<bean id="userFactory" class="com.beans.factory.UserFactory"/> 
<!-- 再引用工廠對象來配置其他Bean -->
<bean id="user" factory-bean="userFactory" factory-method="createPerson">
    <constructor-arg name="id" value="666"></constructor-arg>
	<constructor-arg name="name" value="666"></constructor-arg>
</bean>

調用實例化工廠需要為<bean />指定除id外如下屬性:

  • factory-bean :該屬性指定工廠Bean的id
  • factory-method:該屬性指定實例工廠的工廠方法。
  • 方法參數(shù):如果靜態(tài)工廠方法需要參數(shù),則使用<constructor-arg />元素傳入。

實例工廠和靜態(tài)工廠平時用的不算特別多,平時開發(fā)時用的最多的還是最開始說的構造方法構造。現(xiàn)在有個重要的問題,如果Bean對象的屬性是一個對象呢?這就是我們下面要講的——依賴注入(DI)

三、依賴注入

講spring IOC,不能不講DI,這兩個東西基本上可以說是相輔相成、唇亡齒寒的,所以現(xiàn)在我們就來看看IOC和DI的關系。控制反轉——IOC(Inversion of Control)的意思是創(chuàng)建對象的控制權進行轉移。以前創(chuàng)建對象的主動權和創(chuàng)建時機是由自己把控,而現(xiàn)在這種權力轉移到了spring。

IOC的最重要的一個功能是在系統(tǒng)運行中,動態(tài)的向某個對象提供它所需要的其他對象作為屬性。這一點是通過DI(Dependency Injection,依賴注入)來實現(xiàn)的。下面我來舉一個依賴注入的例子:

比如A類需要使用JBDC,以前我們要在A類中編寫代碼來自己new一個Connection對象(這邊咱先不考慮數(shù)據(jù)庫連接池)?,F(xiàn)在有了 spring,我們就只需要用配置文件告訴spring,A類中需要一個Connection對象,至于這個Connection怎么構造,何時構造,A類不需要知道。在運行時,spring會在適當?shù)臅r候構造一個Connection對象,然后注入到A類當中,這樣就完成了對各個對象之間關系的控制。A類需要依賴Connection這個屬性才能正常運行,而這個Connection對象是由spring注入到A中的,依賴注入的名字就這么來的。

看了這么多,是不是發(fā)現(xiàn)其實依賴注入和我們上文講的屬性注入其實是同一類東西,都是動態(tài)地給對象的屬性賦值,只不過這里的屬性是一個對象,上文講的的屬性是簡單類型而已。依賴注入聽起來很高端,實際上就是給對象的對象屬性賦值而已。

四、Bean的生命周期

講了如何編寫配置文件,那么你一定好奇在spring內部每時每刻這個Bean的狀態(tài)應該是怎么樣的。于是我們就來看看spring中Bean的生命周期。不過,有一點要提前說明,Spring只幫我們管理單例模式(singleton)Bean的完整生命周期,對于 多例模式(prototype)的Bean,Spring 在創(chuàng)建好交給使用者之后則不會再管理后續(xù)的生命周期了。單例模式和多例模式放在后面講。

來看看我們的Bean對象是如何產(chǎn)生的。這個圖乍一看很嚇人,其實里面許多東西都是一些擴展點,他們穿插于Bean的生命周期中,我們一開始不需要去折騰這些擴展點,我們的關注點應該在Bean的生命周期本身。

其實,Bean的生命周期一共只有四個階段,分別是:

  • 實例化 Instantiation
  • 屬性賦值 Populate
  • 初始化 Initialization
  • 銷毀 Destruction

要徹底搞清楚Spring的生命周期,首先要把這四個階段牢牢記住。實例化和屬性賦值對應構造方法和setter方法的注入,初始化和銷毀是用戶能自定義擴展的兩個階段,我們可以自己在這兩個函數(shù)里面書寫我們需要的邏輯。在這四個階段之間穿插的各種擴展點,以后再講。

首先我們先來看前三個,他們的主要邏輯都在doCreateBean方法中,順序調用三個方法,這三個方法與三個生命周期階段一一對應:

//PS:下面的代碼已經(jīng)刪去暫時不用了解的部分,只留下核心部分
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {
   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (instanceWrapper == null) {
       // 實例化
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
       // 屬性賦值
      populateBean(beanName, mbd, instanceWrapper);
       // 初始化
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
}

有了這三個,再加上一個銷毀,組成了Bean的最重要的四個生命周期階段。如下圖所示,當然,下圖除了這四個基本的生命周期階段之外,還加上了一些擴展點:

在這里插入圖片描述

初學時我們只需要知道這些擴展點的存在即可,至于他們具體該怎么用,后面用到的時候會講。我們在這里需要明白的是四個最基本的生命周期。其他的擴展點平時開發(fā)很少用到,但是在讀一些Java中間件源碼的時候,這些擴展點就必須得弄明白了。

Ioc中Bean的作用域

在Spring中,可以在< bean >元素的scope屬性里設置bean的作用域,以決定這個bean是單實例的還是多實例的。

默認情況下,Spring值為每個在IOC容器里聲明的bean創(chuàng)建唯一一個實例,整個Ioc容器范圍內都能共享該實例:所有后續(xù)的getBean()調用和bean引用都將返回這個唯一的bean。該作用域被稱為singleton,它是所有bean的默認作用域。

當bean的作用域為單例時,Spring會在IOC容器對象創(chuàng)建時就創(chuàng)建bean的對象實例。而當bean的作用域為prototype時,Ioc容器在獲取bean的實例時創(chuàng)建bean的實例對象

bean的作用范圍和生命周期

單例對象: scope=“singleton”

  • 一個應用只有一個對象的實例。他的作用范圍就是整個引用
  • 生命周期:
  • 對象出生:當應用加載,創(chuàng)建容器時,對象創(chuàng)建
  • 對象活著:只要容器在,對象一直活著
  • 對象死亡:當應用卸載,銷毀容器時,對象銷毀

多例對象:scope=“prototype”

  • 每次訪問對象時,都會重新創(chuàng)建對象實例
  • 生命周期:
  • 對象出生:當使用對象時,創(chuàng)建新的對象實例
  • 對象活著:只要對象在使用中,就一直活著
  • 對象死亡:當對象長時間不用時,就被java的垃圾回收器回收了。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Spring boot應用啟動后首次訪問很慢的解決方案

    Spring boot應用啟動后首次訪問很慢的解決方案

    這篇文章主要介紹了Spring boot應用啟動后首次訪問很慢的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 使用Java實現(xiàn)MySQL數(shù)據(jù)鎖定的策略

    使用Java實現(xiàn)MySQL數(shù)據(jù)鎖定的策略

    在并發(fā)環(huán)境下,多個線程同時對MySQL數(shù)據(jù)庫進行讀寫操作可能會導致數(shù)據(jù)沖突和不一致的問題,為了解決這些并發(fā)沖突,我們可以采用數(shù)據(jù)鎖定策略來保證數(shù)據(jù)的一致性和完整性,下面將介紹如何使用Java實現(xiàn)MySQL數(shù)據(jù)鎖定策略,,需要的朋友可以參考下
    2023-08-08
  • Springboot如何使用外部yml啟動

    Springboot如何使用外部yml啟動

    這篇文章主要介紹了Springboot如何使用外部yml啟動問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java中Hashtable集合的常用方法詳解

    Java中Hashtable集合的常用方法詳解

    本篇文章給大家?guī)淼膬热菔顷P于Java中Hashtable集合的常用方法詳解,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。下面我們就來學習一下吧
    2021-11-11
  • 詳解SpringBoot如何優(yōu)雅的進行全局異常處理

    詳解SpringBoot如何優(yōu)雅的進行全局異常處理

    在SpringBoot的開發(fā)中,為了提高程序運行的魯棒性,我們經(jīng)常需要對各種程序異常進行處理,但是如果在每個出異常的地方進行單獨處理的話,這會引入大量業(yè)務不相關的異常處理代碼,這篇文章帶大家了解一下如何優(yōu)雅的進行全局異常處理
    2023-07-07
  • Maven發(fā)布項目 (jar包) 到Nexus私服中的操作

    Maven發(fā)布項目 (jar包) 到Nexus私服中的操作

    這篇文章主要介紹了Maven發(fā)布項目 (jar包) 到Nexus私服中的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • springboot @Configuration和@Componment的區(qū)別及說明

    springboot @Configuration和@Componment的區(qū)別及說明

    這篇文章主要介紹了springboot @Configuration和@Componment的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • 在Ubuntu系統(tǒng)下安裝JDK和Tomcat的教程

    在Ubuntu系統(tǒng)下安裝JDK和Tomcat的教程

    這篇文章主要介紹了在Ubuntu系統(tǒng)下安裝JDK和Tomcat的教程,這樣便是在Linux系統(tǒng)下搭建完整的Java和JSP開發(fā)環(huán)境,需要的朋友可以參考下
    2015-08-08
  • Java?輕松入門使用Fiddler抓包工具教程

    Java?輕松入門使用Fiddler抓包工具教程

    超文本傳輸協(xié)議(HTTP)是一個簡單的請求-響應協(xié)議,其主要是基于TCP來實現(xiàn)的,可以通過Chrome開發(fā)者工具或者Wireshark或者Fiddler抓包,以便分析?HTTP?請求/響應的細節(jié),本篇博客主要談論如何使用Fiddler抓取HTTP,當然也可以抓取HTTPS
    2022-02-02
  • Java中Arrays.sort自定義一維數(shù)組、二維數(shù)組的排序方式

    Java中Arrays.sort自定義一維數(shù)組、二維數(shù)組的排序方式

    這篇文章主要介紹了Java中Arrays.sort自定義一維數(shù)組、二維數(shù)組的排序方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08

最新評論

博兴县| 玉山县| 石台县| 清镇市| 襄汾县| 苏尼特左旗| 湖口县| 宣威市| 正阳县| 金平| 库伦旗| 铜鼓县| 南乐县| 桦南县| 邯郸市| 民丰县| 伊川县| 儋州市| 德惠市| 常宁市| 紫云| 岱山县| 射洪县| 高碑店市| 介休市| 富源县| 平乡县| 屯门区| 文安县| 泰来县| 淮北市| 诸暨市| 永吉县| 冕宁县| 瓮安县| 赫章县| 阳山县| 永新县| 永吉县| 仁寿县| 清丰县|