注:以下那些受Spring IOC容器即BeanFactory控制管理的對象簡稱bean對象
一. BeanFactory
作爲整個Spring IOC容器核心Interface BeanFacotry被放在包 org.springframework.beans.factory中,這是一個非常簡單的接口,如果Spring現有的BeanFactory的實現無法滿足你的要求(這種情況應該不多J),你可以很容易創建自己的一個實現。
public interface BeanFactory {
Object getBean(String name) throws BeansException;
Object getBean(String name, Class requiredType) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name) throws NoSuchBeanDefinitionException;
}
這就是BeanFactory的代碼,總共有5個函數所組成,2個getBean函數提供根據String類型的名稱來尋找受BeanFactory的bean對象,區別在於其中一個函數提供了類型檢測的功能,來檢測取得bean對象是否爲所需的類型,如果類型不符將拋出一個BeanNotOfRequiredTypeException的異常。
函數isSingleton 則用來判斷BeanFactory的bean對象被定義爲Singleton還是Prototype。如果被定義爲Singleton的話,在BeanFactory的生命週期內,所有對getBean的調用將返回一個bean對象的實例引用,如果是Prototype則每次調用getBean對會創建一個獨立的對象實例。
如果一個bean對象被定義了別名,那麼函數getAliases就可以用來取得該bean對象的所有別名。
二. 使用BeanFactory
前面介紹了Spring IOC容器的核心Interface BeanFactory,現在我們通過一個的例子來簡單的瞭解如何使用BeanFactory。這個例子中,使用了BeanFactory最常用的幾個實現之一XMLBeanFactory,這個BeanFactory實現是通過XML來組裝bean對象的(當然BeanFactory 還有一個實現是通過Java配置文件.propeties來組裝bean對象)。
例子有1個Interface 和3個Class所組成,先來看Interface:
package net.hashmap.spring.ioc.example.dao;
public interface AbstractDAO {
public void insert();
public void update();
public void delete();
public void get();
}
AbstractDAO這個接口定義了4個訪問數據庫的方法,然後來看看AbstractDAO的2個實現HibernateDAO和JDBCDAO。
package net.hashmap.spring.ioc.example.dao.support;
import net.hashmap.spring.ioc.example.dao.AbstractDAO;
public class HibernateDAO implements AbstractDAO {
public void insert() {
System.out.println("This is HibernateDAO.insert");
}
public void update() {
System.out.println("This is HibernateDAO.update");
}
public void delete() {
System.out.println("This is HibernateDAO.delete");
}
public void get() {
System.out.println("This is HibernateDAO.get");
}
}
package net.hashmap.spring.ioc.example.dao.support;
import net.hashmap.spring.ioc.example.dao.AbstractDAO;
public class JdbcDAO implements AbstractDAO {
public void insert() {
System.out.println("This is JdbcDAO.insert");
}
public void update() {
System.out.println("This is JdbcDAO.update");
}
public void delete() {
System.out.println("This is JdbcDAO.delete");
}
public void get() {
System.out.println("This is JdbcDAO.get");
}
}
這2個Class都實現了AbstractDAO,但是一個提供了通過Hibernate來訪問數據庫,而另外一個則使用了JDBC(具體和數據庫交互的代碼,不在討論範疇內)。
現在再來看看具體的模擬業務邏輯的Class
package net.hashmap.spring.ioc.example.logic;
import net.hashmap.spring.ioc.example.dao.AbstractDAO;
public class LogicBusinessImpl {
private AbstractDAO _dao;
public AbstractDAO getDao() {
return _dao;
}
public void setDao(AbstractDAO _dao) {
this._dao = _dao;
}
public void BusinessHandle() {
_dao.insert();
_dao.get();
_dao.update();
_dao.delete();
}
}
LogicBusinessImpl定義了一個方法getDao,這個getter就是用來給IOC容器進行依賴注入的。
接着就是相當重要的組裝bean對象的xml。
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="hibernatedao" class="net.hashmap.spring.ioc.example.dao.support.HibernateDAO" />
<bean id="jdbcdao" class="net.hashmap.spring.ioc.example.dao.support.JdbcDAO" />
<bean id="HLogicImpl" class="net.hashmap.spring.ioc.example.logic.LogicBusinessImpl">
<property name="dao">
<ref local="hibernatedao" />
</property>
</bean>
<bean id="JLogicImpl" class="net.hashmap.spring.ioc.example.logic.LogicBusinessImpl">
<property name="dao">
<ref local="jdbcdao" />
</property>
</bean>
</beans>
Xml文件裏總共組裝了2個LogicBusinessImpl,一個的使用HibernateDAO來作爲bean對象的DAO,另一個則使用了JdbcDAO。通過這樣組裝bean對象,我們就可以不用在bean對象中顯示的聲明所依賴的對象,從而降低了對象間的依賴程度,同時由於我們依賴的只有一個接口,所以這樣的代碼更容易測試。
再來看看我們如何使用Spring的BeanFactory
Resource res = new ClassPathResource("bean.xml");
XmlBeanFactory bf = new XmlBeanFactory(res);
LogicBusinessImpl HbuisImpl = (LogicBusinessImpl ) bf.getBean("HLogicImpl");
HbuisImpl.BusinessHandle();
System.out.println("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\");
LogicBusinessImpl JBuisImpl = (LogicBusinessImpl ) bf.getBean("JLogicImpl");
JBuisImpl.BusinessHandle();
XmlBeanFactory 通過ClassPathResource來讀入組裝bean對象的xml文件,Spring 不光提供了訪問Classpath的ClassPathResource,還有訪問文件路徑的FileSystemResource,訪問Url的UrlResource,以及流形式的InputStreamResource。
以上就是使用Spring的XmlBeanFactory做的一個example,例子很簡單,但是後續針對Spring IOC的學習都會基於這個例子。