spring每次getBean(),獲得的是否是同一個實例

spring 缺省:
  • 1.spring用DefaultListableBeanFactory.preInstantiateSingletons()建立bean實例
  • 2.缺省採用單例模式

測試基本bean:
xml配置文件:
<bean id="dvdTypeDAO" class="com.machome.hibernate.impl.DvdTypeDAOImpl" />   
測試代碼:
        ctx = new ClassPathXmlApplicationContext("spring-hibernate-mysql.xml");
        DvdTypeDAO tDao1 = (DvdTypeDAO)ctx.getBean("dvdTypeDAO");
        DvdTypeDAO tDao2 = (DvdTypeDAO)ctx.getBean("dvdTypeDAO");
運行:        
true
com.machome.hibernate.impl.DvdTypeDAOImpl@15b0333
com.machome.hibernate.impl.DvdTypeDAOImpl@15b0333

說明前後兩次getBean()獲得的是同一實例,說明spring缺省是單例


改scope爲多實例
<bean id="dvdTypeDAO" class="com.machome.hibernate.impl.DvdTypeDAOImpl" scope="prototype" />
 
執行同樣的測試代碼
運行:
false
com.machome.hibernate.impl.DvdTypeDAOImpl@afae4a
com.machome.hibernate.impl.DvdTypeDAOImpl@1db9852
說明scope="prototype"後,每次getBean()的都是不同的新實例



使用spring 的時候, 你應該先問問自己,你編一個類,初衷,是否就是準備採用單例? 是否就是準備內部設靜態實例,私有化構造方法,靜態塊初始化,靜態getInstance() 方法?
我們可以借鑑一個框架的設計思想和經驗,但不要讓它幫我們做選擇!!!



以此類推,spring 提供給hibernate的SessionFactory是否是單例?
sessionFactory bean 由spring的對應的SessionFactory類建立的bean, 按數據庫類型,分爲hibernate,JPA等幾種,按操作類型,分爲專爲xml配置文件設計的的和專爲標註設計的
sessionFactory bean 儘管是"工廠",但那是指它建立session的功能.它相對於spring來說,仍是一個普通的bean,通常把它作爲屬性注入到其他需要session的DAO bean中.
所以sessionFactory bean 自身的建立仍採用spring的缺省工廠類,自然缺省也是單例的.
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
    <property name="dataSource" ref="dataSource" />
    <property name="mappingResources">
        <list>
            <value>org/machome/hibernate/DvdType.hbm.xml</value>   
        </list>
    </property>  
    <property name="hibernateProperties">                   
        <value>
            hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
            hibernate.hbm2ddl.auto=update         
        </value>
    </property>
</bean>

<bean id="dvdTypeDAO" class="com.machome.hibernate.impl.DvdTypeDAOImpl">
   <property name="seasonFactory" ref="seasonFactory"/>
</bean>
測試代碼:
        ctx = new ClassPathXmlApplicationContext("spring-hibernate-mysql.xml");
        SessionFactory tDao1 = (SessionFactory)ctx.getBean("sessionFactory");
        SessionFactory tDao2 = (SessionFactory)ctx.getBean("sessionFactory");
        
        System.out.println(tDao1==tDao2);
        System.out.println(tDao1);
        System.out.println(tDao2);
運行:
true
org.hibernate.impl.SessionFactoryImpl@12c5431
org.hibernate.impl.SessionFactoryImpl@12c5431


DataSource bean 是否是單例?
DataSource bean通常把它作爲屬性注入到sessionFactory bean中
它自身仍是普通bean,採用spring的缺省工廠類,自然缺省也是單例的

apacha dbcp datasource
        ctx = new ClassPathXmlApplicationContext("spring-hibernate-mysql.xml");
        BasicDataSource tDao1 = (BasicDataSource)ctx.getBean("dataSource");
        BasicDataSource tDao2 = (BasicDataSource)ctx.getBean("dataSource");
        
        System.out.println(tDao1==tDao2);
        System.out.println(tDao1);
        System.out.println(tDao2);
true
org.apache.commons.dbcp.BasicDataSource@ab7165
org.apache.commons.dbcp.BasicDataSource@ab7165

c3p0 datasource
        ComboPooledDataSource tDao1 = (ComboPooledDataSource)ctx.getBean("dataSource");
        ComboPooledDataSource tDao2 = (ComboPooledDataSource)ctx.getBean("dataSource");
        
        System.out.println(tDao1==tDao2);
        System.out.println(tDao1);
        System.out.println(tDao2);
true
com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, ... ]

com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, ... ]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章