實例化bean的三種方式


 

第一種: 使用無參構造函數(重點第一種,二三種已經沒太多人用了)

 

 

hi是一個簡單的bean , 只有println();

<bean id="binbin" class="test_one.hi"></bean>

id 是唯一標識, class是類路徑(src/main/java是默認路徑,不可更改,所以必須在該目錄下添加包,並且為了能找到該類,該類需要在頭上加package,很顯然兩者是對應的)

scope: 指定對象作用范圍  singleton : 默認值,單例模式(只要被實例化,該實例就會一直存活,除非容器銷毀或退出,並且IoC容器只存在一個實例,所有對該對象的引用將共享這個實例) prototype: 多例模式(每次請求都將創建一個新的實例,當實例長時間不用會被java的垃圾回收機制回收)

request, session, global session 這三種只適用於web應用程序,通常是與XmlWebApplicationContext共同使用

單例模式:

 

 多例模式:

 

 如果創建一個新的實例classpathxmlapplicationcontext, 他們之間的地址是不一樣的,由於ApplicationContext是繼承BeanFactory,所以我們可以說

在同一個容器內,單例模式下的實例為同一實例,在同一容器內訪問該實例為同一實例,引用對象共享實例

 

 

從上面的singleton模式我們就能明白,為什么一個實例可以一直存在並且對該對象的引用都共享這個實例. 如果這個實例要不一樣的屬性呢?

bean就是可復用的類, 因為有的類每次我們實例化就只要用里面的函數,  不需要將實例當作數據一樣對待..而bean的出現就解決了繁瑣地創建實例以及浪費內存資源

那為什么是無參構造函數呢? 因為可復用類不能用有參構造函數

 

下面是如何從配置文件中獲得實例化bean

可以看出,我們通過bean.xml文件,通過getBean(唯一標識id)得到我們想要的對象,而不用我們主動去創建對象,這就是典型的工廠模式。 getBean是BeanFactory接口的方法,返回得對應id的實例。

 

 

第二種 :使用靜態工廠創建

bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--使用無參構造函數實例化-->
<bean id="binbin" class="test_one.hi"></bean>
<!--使用靜態工廠實例化-->
<bean id="static" class="test_one.static_test" factory-method="sayStatic"></bean>

</beans>

id 唯一標識; class 類路徑;   factory-method 工廠方法名

static_test類

 

 

如何通過靜態工廠得到實例

 

 第一種是直接從配置文件bean.xml得到實例,而第二種是從配置文件bean.xml尋找對應的靜態方法,再從靜態方法返回實例。

那么靜態工廠是單例模式嗎? 就是每次調用的時候不會創建新的實例,會共享實例。

在spring中默認是單例模式, 不在spring是多例

下圖為不在spring中

 

 

靜態工廠與單例模式的區別

第三種: 實例工廠創建實例

 普通方法無法像靜態方法一樣實現單例模式,而實例工廠就是讓普通方法可以和靜態方法一樣實現單例模式

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--使用無參構造函數實例化-->
<bean id="binbin" class="test_one.hi" scope="prototype"></bean>
<!--使用靜態工廠實例化-->
<bean id="static" class="test_one.static_test" factory-method="sayStatic"></bean>
<!--使用實例工廠實例化-->
<bean id="instance" class="test_one.instance"></bean>
<bean id="createInstance" factory-bean="instance" factory-method="createHi"></bean>
</beans>

instance.java

 

 

 

得到實例化

 

 第三種有點復雜

靜態工廠模式和實例模式都會多實例化一個對象,也就是靜態方法或者方法所在的類

以上三種實例化bean的方法, 在程序開始運行后就已經實例化了, 如果在bean中加入構造函數就會發現哪怕沒有獲取實例化也執行了構造函數, 這就說明開始就已經實例化了

 參考:

Bean的3種實例化

Bean的3種實例化

非實例化bean, 抽象bean:

abstract屬性為true,表示該bean為抽象bean,不會被實例化,但是其屬性可以注入到其它bean中

抽象bean的一個好處就是做模板 , 如果兩個類有相同的屬性,那么可以注入抽象bean來解決通過兩次重復操作來注入該屬性

abstract="true"

//兩個有相同屬性的類(不用聲明父類)
public class FooDao {
    private DataSource dataSource;
    private SomeHelper someHelper;
    private FooHelper fooHelper;
 
    //setters
}
public class BarDao {
    private DataSource dataSource;
    private SomeHelper someHelper;
    private BarHelper barHelper;
 
    //setters
}
//xml定義抽象bean(並不會實例化這個bean)
<bean id="dao" abstract="true"> <!--實際根本沒有這個類-->
    <property name="dataSource" ref="dataSource"/>
    <property name="someHelper" ref="someHelper"/>
</bean>
 
 <!--指定parent為dao,則只需要再注入自己特別的屬性即可-->
<bean id="fooDao" class="FooDao" parent="dao">
    <property name="fooHelper" ref="fooHelper" />
</bean>
<bean id="barDao" class="BarDao" parent="dao">
    <property name="barHelper" ref="barHelper" />
</bean>

抽象bean不是指抽象類,其實根本就沒有這個類

抽象bean的屬性在子bean一定是擁有的, 如果沒有就會報錯

如果子bean注入了數據, 那么取得是子bean的值

如果有多個bean有相同的屬性並且值也相同(個別bean不同) , 那么可以用抽象bean來注入相同的屬性, 並且還不影響個別子bean的值不同

所以抽象bean作為模板特別好


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM