建立我們的業務服務對象
我們將在我們的業務對象中使用的setter方法接受的是接口,這些接口允許對象的松散定義的實現,這些對象將被設置或者注入。在我們這個例子里我們將使我們的業務服務對象接受一個DAO去控制我們的領域對象的持久化。當我們在這篇文章的例子中使用Hibernate,我們可以容易的轉換到一個不同的持久框架的實現,通知Spring使用新的實現的DAO對象。你能明白編程到接口和使用“依賴注入”模式是怎樣寬松耦合你的業務邏輯和你的持久化機制的。
這兒是業務服務對象的接口,它是一個DAO對象依賴的樁.
注意上面的代碼有一個為DAO對象準備的setter方法。這兒沒有一個getOrderDAO方法因為它不是必要的,因為不太有從外面訪問連著的OrderDAO對象的需要。DAO對象將被用來和我們的持久層溝通。我們將用Spring把業務服務對象和DAO對象連在一起。因為我們編碼到接口,我們不會緊耦合實現。
下一步是寫我們的DAO實現對象。因為Spring有內建的對Hibernate的支持,這個例子DAO將繼承HibernateDaoSupport類,這使得我們容易取得一個到HibernateTemplate類的引用,HibernateTemplate是一個幫助類,它能簡化Hibernate Session的編碼和處理HibernateExceptions。這兒是DAO的接口:
我們還有兩個對象要和我們的業務層連在一起。這包括HibernateSessionFactory和一個TransactionManager對象。這在Spring配置文件里直接完成。Spring提供一個HibernateTransactionManager,它將從工廠綁定一個Hibernate Session到一個線程來支持事務。這兒是HibernateSessionFactory和HibernateTransactionManager的Spring配置。
每一個對象能被Spring配置里的一個<bean>標記引用。在這個例子里,bean “mySessionFactory”代表一個HibernateSessionFactory,bean “myTransactionManager”代表一個Hibernate transaction manager。注意transactionManger bean有一個叫作sessionFactory的屬性元素。HibernateTransactionManager有一個為sessionFactory準備的setter和getter方法,它們是用來當Spring容器啟動時的依賴注入。sessionFactory屬性引用mySessionFactory bean。這兩個對象現在當Spring容器初始化時將被連在一起。這種連接把你從為引用和創建這些對象而創建singleton對象和工廠中解放出來,這減少了你應用程序中的代碼維護。mySessionFactory bean有兩個屬性元素,它們翻譯成為mappingResources 和 hibernatePropertes準備的setter方法。通常,如果你在Spring之外使用Hibernate,這個配置將被保存在hibernate.cfg.xml文件中。不管怎樣,Spring提供了一個便捷的方式--在Spring配置文件中合并Hibernate的配置。
既然我們已經配置了我們的容器服務beans和把它們連在了一起,我們需要把我們的業務服務對象和我們的DAO對象連在一起。然后,我們需要把這些對象連接到事務管理器。
這是在Spring配置文件里的樣子:
圖4是我們已經連在一起的東西的一個概覽。它展示了每個對象是怎樣相關聯的和怎樣被Spring設置進其它對象中。把這幅圖和示例應用中的Spring配置文件對比查看它們之間的關系。

圖4:這是Spring怎樣將在這個配置的基礎上裝配beans。
這個例子使用一個TransactionProxyFactoryBean,它有一個為我們已經定義了的事務管理者準備的setter方法。這是一個有用的對象,它知道怎樣處理聲明的事務操作和你的服務對象。你可以通過transactionAttributes屬性定義事務怎樣被處理,transactionAttributes屬性為方法名定義模式和它們怎樣參與進一個事務。
TransactionProxyFactoryBean類也有一個為一個target準備的setter,target將是一個到我們的叫作orderTarget的業務服務對象的引用。 orderTarget bean定義使用哪個業務服務對象并有一個指向setOrderDAO()的屬性。orderDAO bean將居于這個屬性中,orderDAO bean是我們的和持久層交流的DAO對象。
還有一個關于Spring和bean要注意的是bean能以兩種模式工作。這兩種模式被定義為singleton和prototype。一個bean默認的模式是singleton,意味著一個共享的bean的實例將被管理。這是用于無狀態操作--像一個無狀態會話bean將提供的那樣。當bean由Spring提供時,prototype模式允許創建bean的新實例。你應當只有在每一個用戶都需要他們自己的bean的拷貝時才使用prototype模式。
我們將在我們的業務對象中使用的setter方法接受的是接口,這些接口允許對象的松散定義的實現,這些對象將被設置或者注入。在我們這個例子里我們將使我們的業務服務對象接受一個DAO去控制我們的領域對象的持久化。當我們在這篇文章的例子中使用Hibernate,我們可以容易的轉換到一個不同的持久框架的實現,通知Spring使用新的實現的DAO對象。你能明白編程到接口和使用“依賴注入”模式是怎樣寬松耦合你的業務邏輯和你的持久化機制的。
這兒是業務服務對象的接口,它是一個DAO對象依賴的樁.
public interface IOrderService { public abstract Order saveNewOrder(Order order) throws OrderException, OrderMinimumAmountException; public abstract List findOrderByUser(String user) throws OrderException; public abstract Order findOrderById(int id) throws OrderException; public abstract void setOrderDAO(IOrderDAO orderDAO); } |
注意上面的代碼有一個為DAO對象準備的setter方法。這兒沒有一個getOrderDAO方法因為它不是必要的,因為不太有從外面訪問連著的OrderDAO對象的需要。DAO對象將被用來和我們的持久層溝通。我們將用Spring把業務服務對象和DAO對象連在一起。因為我們編碼到接口,我們不會緊耦合實現。
下一步是寫我們的DAO實現對象。因為Spring有內建的對Hibernate的支持,這個例子DAO將繼承HibernateDaoSupport類,這使得我們容易取得一個到HibernateTemplate類的引用,HibernateTemplate是一個幫助類,它能簡化Hibernate Session的編碼和處理HibernateExceptions。這兒是DAO的接口:
public interface IOrderDAO { public abstract Order findOrderById(final int id); public abstract List findOrdersPlaceByUser(final String placedBy); public abstract Order saveOrder(final Order order); } |
我們還有兩個對象要和我們的業務層連在一起。這包括HibernateSessionFactory和一個TransactionManager對象。這在Spring配置文件里直接完成。Spring提供一個HibernateTransactionManager,它將從工廠綁定一個Hibernate Session到一個線程來支持事務。這兒是HibernateSessionFactory和HibernateTransactionManager的Spring配置。
<bean id="mySessionFactory" class="org.springframework.orm.hibernate. LocalSessionFactoryBean"> <property name="mappingResources"> <list> <value> com/meagle/bo/Order.hbm.xml </value> <value> com/meagle/bo/OrderLineItem.hbm.xml </value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> net.sf.hibernate.dialect.MySQLDialect </prop> <prop key="hibernate.show_sql"> false </prop> <prop key="hibernate.proxool.xml"> C:/MyWebApps/.../WEB-INF/proxool.xml </prop> <prop key="hibernate.proxool.pool_alias"> spring </prop> </props> </property> </bean> <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --> <bean id="myTransactionManager" class="org. springframework. orm. hibernate. HibernateTransactionManager"> <property name="sessionFactory"> <ref local="mySessionFactory"/> </property> </bean> |
每一個對象能被Spring配置里的一個<bean>標記引用。在這個例子里,bean “mySessionFactory”代表一個HibernateSessionFactory,bean “myTransactionManager”代表一個Hibernate transaction manager。注意transactionManger bean有一個叫作sessionFactory的屬性元素。HibernateTransactionManager有一個為sessionFactory準備的setter和getter方法,它們是用來當Spring容器啟動時的依賴注入。sessionFactory屬性引用mySessionFactory bean。這兩個對象現在當Spring容器初始化時將被連在一起。這種連接把你從為引用和創建這些對象而創建singleton對象和工廠中解放出來,這減少了你應用程序中的代碼維護。mySessionFactory bean有兩個屬性元素,它們翻譯成為mappingResources 和 hibernatePropertes準備的setter方法。通常,如果你在Spring之外使用Hibernate,這個配置將被保存在hibernate.cfg.xml文件中。不管怎樣,Spring提供了一個便捷的方式--在Spring配置文件中合并Hibernate的配置。
既然我們已經配置了我們的容器服務beans和把它們連在了一起,我們需要把我們的業務服務對象和我們的DAO對象連在一起。然后,我們需要把這些對象連接到事務管理器。
這是在Spring配置文件里的樣子:
<!-- ORDER SERVICE --> <bean id="orderService" class="org. springframework. transaction. interceptor. TransactionProxyFactoryBean"> <property name="transactionManager"> <ref local="myTransactionManager"/> </property> <property name="target"> <ref local="orderTarget"/> </property> <property name="transactionAttributes"> <props> <prop key="find*"> PROPAGATION_REQUIRED,readOnly,-OrderException </prop> <prop key="save*"> PROPAGATION_REQUIRED,-OrderException </prop> </props> </property> </bean> <!-- ORDER TARGET PRIMARY BUSINESS OBJECT: Hibernate implementation --> <bean id="orderTarget" class="com. meagle. service. spring. OrderServiceSpringImpl"> <property name="orderDAO"> <ref local="orderDAO"/> </property> </bean> <!-- ORDER DAO OBJECT --> <bean id="orderDAO" class="com. meagle. service. dao. hibernate. OrderHibernateDAO"> <property name="sessionFactory"> <ref local="mySessionFactory"/> </property> </bean> |
圖4是我們已經連在一起的東西的一個概覽。它展示了每個對象是怎樣相關聯的和怎樣被Spring設置進其它對象中。把這幅圖和示例應用中的Spring配置文件對比查看它們之間的關系。

圖4:這是Spring怎樣將在這個配置的基礎上裝配beans。
這個例子使用一個TransactionProxyFactoryBean,它有一個為我們已經定義了的事務管理者準備的setter方法。這是一個有用的對象,它知道怎樣處理聲明的事務操作和你的服務對象。你可以通過transactionAttributes屬性定義事務怎樣被處理,transactionAttributes屬性為方法名定義模式和它們怎樣參與進一個事務。
TransactionProxyFactoryBean類也有一個為一個target準備的setter,target將是一個到我們的叫作orderTarget的業務服務對象的引用。 orderTarget bean定義使用哪個業務服務對象并有一個指向setOrderDAO()的屬性。orderDAO bean將居于這個屬性中,orderDAO bean是我們的和持久層交流的DAO對象。
還有一個關于Spring和bean要注意的是bean能以兩種模式工作。這兩種模式被定義為singleton和prototype。一個bean默認的模式是singleton,意味著一個共享的bean的實例將被管理。這是用于無狀態操作--像一個無狀態會話bean將提供的那樣。當bean由Spring提供時,prototype模式允許創建bean的新實例。你應當只有在每一個用戶都需要他們自己的bean的拷貝時才使用prototype模式。