- 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, ... ] |