建立我們的業(yè)務(wù)服務(wù)對(duì)象
我們將在我們的業(yè)務(wù)對(duì)象中使用的setter方法接受的是接口,這些接口允許對(duì)象的松散定義的實(shí)現(xiàn),這些對(duì)象將被設(shè)置或者注入。在我們這個(gè)例子里我們將使我們的業(yè)務(wù)服務(wù)對(duì)象接受一個(gè)DAO去控制我們的領(lǐng)域?qū)ο蟮某志没.?dāng)我們?cè)谶@篇文章的例子中使用Hibernate,我們可以容易的轉(zhuǎn)換到一個(gè)不同的持久框架的實(shí)現(xiàn),通知Spring使用新的實(shí)現(xiàn)的DAO對(duì)象。你能明白編程到接口和使用“依賴(lài)注入”模式是怎樣寬松耦合你的業(yè)務(wù)邏輯和你的持久化機(jī)制的。
這兒是業(yè)務(wù)服務(wù)對(duì)象的接口,它是一個(gè)DAO對(duì)象依賴(lài)的樁.
注意上面的代碼有一個(gè)為DAO對(duì)象準(zhǔn)備的setter方法。這兒沒(méi)有一個(gè)getOrderDAO方法因?yàn)樗皇潜匾模驗(yàn)椴惶袕耐饷嬖L(fǎng)問(wèn)連著的OrderDAO對(duì)象的需要。DAO對(duì)象將被用來(lái)和我們的持久層溝通。我們將用Spring把業(yè)務(wù)服務(wù)對(duì)象和DAO對(duì)象連在一起。因?yàn)槲覀兙幋a到接口,我們不會(huì)緊耦合實(shí)現(xiàn)。
下一步是寫(xiě)我們的DAO實(shí)現(xiàn)對(duì)象。因?yàn)镾pring有內(nèi)建的對(duì)Hibernate的支持,這個(gè)例子DAO將繼承HibernateDaoSupport類(lèi),這使得我們?nèi)菀兹〉靡粋€(gè)到HibernateTemplate類(lèi)的引用,HibernateTemplate是一個(gè)幫助類(lèi),它能簡(jiǎn)化Hibernate Session的編碼和處理HibernateExceptions。這兒是DAO的接口:
我們還有兩個(gè)對(duì)象要和我們的業(yè)務(wù)層連在一起。這包括HibernateSessionFactory和一個(gè)TransactionManager對(duì)象。這在Spring配置文件里直接完成。Spring提供一個(gè)HibernateTransactionManager,它將從工廠(chǎng)綁定一個(gè)Hibernate Session到一個(gè)線(xiàn)程來(lái)支持事務(wù)。這兒是HibernateSessionFactory和HibernateTransactionManager的Spring配置。
每一個(gè)對(duì)象能被Spring配置里的一個(gè)<bean>標(biāo)記引用。在這個(gè)例子里,bean “mySessionFactory”代表一個(gè)HibernateSessionFactory,bean “myTransactionManager”代表一個(gè)Hibernate transaction manager。注意transactionManger bean有一個(gè)叫作sessionFactory的屬性元素。HibernateTransactionManager有一個(gè)為sessionFactory準(zhǔn)備的setter和getter方法,它們是用來(lái)當(dāng)Spring容器啟動(dòng)時(shí)的依賴(lài)注入。sessionFactory屬性引用mySessionFactory bean。這兩個(gè)對(duì)象現(xiàn)在當(dāng)Spring容器初始化時(shí)將被連在一起。這種連接把你從為引用和創(chuàng)建這些對(duì)象而創(chuàng)建singleton對(duì)象和工廠(chǎng)中解放出來(lái),這減少了你應(yīng)用程序中的代碼維護(hù)。mySessionFactory bean有兩個(gè)屬性元素,它們翻譯成為mappingResources 和 hibernatePropertes準(zhǔn)備的setter方法。通常,如果你在Spring之外使用Hibernate,這個(gè)配置將被保存在hibernate.cfg.xml文件中。不管怎樣,Spring提供了一個(gè)便捷的方式--在Spring配置文件中合并Hibernate的配置。
既然我們已經(jīng)配置了我們的容器服務(wù)beans和把它們連在了一起,我們需要把我們的業(yè)務(wù)服務(wù)對(duì)象和我們的DAO對(duì)象連在一起。然后,我們需要把這些對(duì)象連接到事務(wù)管理器。
這是在Spring配置文件里的樣子:
圖4是我們已經(jīng)連在一起的東西的一個(gè)概覽。它展示了每個(gè)對(duì)象是怎樣相關(guān)聯(lián)的和怎樣被Spring設(shè)置進(jìn)其它對(duì)象中。把這幅圖和示例應(yīng)用中的Spring配置文件對(duì)比查看它們之間的關(guān)系。

圖4:這是Spring怎樣將在這個(gè)配置的基礎(chǔ)上裝配beans。
這個(gè)例子使用一個(gè)TransactionProxyFactoryBean,它有一個(gè)為我們已經(jīng)定義了的事務(wù)管理者準(zhǔn)備的setter方法。這是一個(gè)有用的對(duì)象,它知道怎樣處理聲明的事務(wù)操作和你的服務(wù)對(duì)象。你可以通過(guò)transactionAttributes屬性定義事務(wù)怎樣被處理,transactionAttributes屬性為方法名定義模式和它們?cè)鯓訁⑴c進(jìn)一個(gè)事務(wù)。
TransactionProxyFactoryBean類(lèi)也有一個(gè)為一個(gè)target準(zhǔn)備的setter,target將是一個(gè)到我們的叫作orderTarget的業(yè)務(wù)服務(wù)對(duì)象的引用。 orderTarget bean定義使用哪個(gè)業(yè)務(wù)服務(wù)對(duì)象并有一個(gè)指向setOrderDAO()的屬性。orderDAO bean將居于這個(gè)屬性中,orderDAO bean是我們的和持久層交流的DAO對(duì)象。
還有一個(gè)關(guān)于Spring和bean要注意的是bean能以?xún)煞N模式工作。這兩種模式被定義為singleton和prototype。一個(gè)bean默認(rèn)的模式是singleton,意味著一個(gè)共享的bean的實(shí)例將被管理。這是用于無(wú)狀態(tài)操作--像一個(gè)無(wú)狀態(tài)會(huì)話(huà)bean將提供的那樣。當(dāng)bean由Spring提供時(shí),prototype模式允許創(chuàng)建bean的新實(shí)例。你應(yīng)當(dāng)只有在每一個(gè)用戶(hù)都需要他們自己的bean的拷貝時(shí)才使用prototype模式。
我們將在我們的業(yè)務(wù)對(duì)象中使用的setter方法接受的是接口,這些接口允許對(duì)象的松散定義的實(shí)現(xiàn),這些對(duì)象將被設(shè)置或者注入。在我們這個(gè)例子里我們將使我們的業(yè)務(wù)服務(wù)對(duì)象接受一個(gè)DAO去控制我們的領(lǐng)域?qū)ο蟮某志没.?dāng)我們?cè)谶@篇文章的例子中使用Hibernate,我們可以容易的轉(zhuǎn)換到一個(gè)不同的持久框架的實(shí)現(xiàn),通知Spring使用新的實(shí)現(xiàn)的DAO對(duì)象。你能明白編程到接口和使用“依賴(lài)注入”模式是怎樣寬松耦合你的業(yè)務(wù)邏輯和你的持久化機(jī)制的。
這兒是業(yè)務(wù)服務(wù)對(duì)象的接口,它是一個(gè)DAO對(duì)象依賴(lài)的樁.
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); } |
注意上面的代碼有一個(gè)為DAO對(duì)象準(zhǔn)備的setter方法。這兒沒(méi)有一個(gè)getOrderDAO方法因?yàn)樗皇潜匾模驗(yàn)椴惶袕耐饷嬖L(fǎng)問(wèn)連著的OrderDAO對(duì)象的需要。DAO對(duì)象將被用來(lái)和我們的持久層溝通。我們將用Spring把業(yè)務(wù)服務(wù)對(duì)象和DAO對(duì)象連在一起。因?yàn)槲覀兙幋a到接口,我們不會(huì)緊耦合實(shí)現(xiàn)。
下一步是寫(xiě)我們的DAO實(shí)現(xiàn)對(duì)象。因?yàn)镾pring有內(nèi)建的對(duì)Hibernate的支持,這個(gè)例子DAO將繼承HibernateDaoSupport類(lèi),這使得我們?nèi)菀兹〉靡粋€(gè)到HibernateTemplate類(lèi)的引用,HibernateTemplate是一個(gè)幫助類(lèi),它能簡(jiǎn)化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); } |
我們還有兩個(gè)對(duì)象要和我們的業(yè)務(wù)層連在一起。這包括HibernateSessionFactory和一個(gè)TransactionManager對(duì)象。這在Spring配置文件里直接完成。Spring提供一個(gè)HibernateTransactionManager,它將從工廠(chǎng)綁定一個(gè)Hibernate Session到一個(gè)線(xiàn)程來(lái)支持事務(wù)。這兒是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> |
每一個(gè)對(duì)象能被Spring配置里的一個(gè)<bean>標(biāo)記引用。在這個(gè)例子里,bean “mySessionFactory”代表一個(gè)HibernateSessionFactory,bean “myTransactionManager”代表一個(gè)Hibernate transaction manager。注意transactionManger bean有一個(gè)叫作sessionFactory的屬性元素。HibernateTransactionManager有一個(gè)為sessionFactory準(zhǔn)備的setter和getter方法,它們是用來(lái)當(dāng)Spring容器啟動(dòng)時(shí)的依賴(lài)注入。sessionFactory屬性引用mySessionFactory bean。這兩個(gè)對(duì)象現(xiàn)在當(dāng)Spring容器初始化時(shí)將被連在一起。這種連接把你從為引用和創(chuàng)建這些對(duì)象而創(chuàng)建singleton對(duì)象和工廠(chǎng)中解放出來(lái),這減少了你應(yīng)用程序中的代碼維護(hù)。mySessionFactory bean有兩個(gè)屬性元素,它們翻譯成為mappingResources 和 hibernatePropertes準(zhǔn)備的setter方法。通常,如果你在Spring之外使用Hibernate,這個(gè)配置將被保存在hibernate.cfg.xml文件中。不管怎樣,Spring提供了一個(gè)便捷的方式--在Spring配置文件中合并Hibernate的配置。
既然我們已經(jīng)配置了我們的容器服務(wù)beans和把它們連在了一起,我們需要把我們的業(yè)務(wù)服務(wù)對(duì)象和我們的DAO對(duì)象連在一起。然后,我們需要把這些對(duì)象連接到事務(wù)管理器。
這是在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是我們已經(jīng)連在一起的東西的一個(gè)概覽。它展示了每個(gè)對(duì)象是怎樣相關(guān)聯(lián)的和怎樣被Spring設(shè)置進(jìn)其它對(duì)象中。把這幅圖和示例應(yīng)用中的Spring配置文件對(duì)比查看它們之間的關(guān)系。

圖4:這是Spring怎樣將在這個(gè)配置的基礎(chǔ)上裝配beans。
這個(gè)例子使用一個(gè)TransactionProxyFactoryBean,它有一個(gè)為我們已經(jīng)定義了的事務(wù)管理者準(zhǔn)備的setter方法。這是一個(gè)有用的對(duì)象,它知道怎樣處理聲明的事務(wù)操作和你的服務(wù)對(duì)象。你可以通過(guò)transactionAttributes屬性定義事務(wù)怎樣被處理,transactionAttributes屬性為方法名定義模式和它們?cè)鯓訁⑴c進(jìn)一個(gè)事務(wù)。
TransactionProxyFactoryBean類(lèi)也有一個(gè)為一個(gè)target準(zhǔn)備的setter,target將是一個(gè)到我們的叫作orderTarget的業(yè)務(wù)服務(wù)對(duì)象的引用。 orderTarget bean定義使用哪個(gè)業(yè)務(wù)服務(wù)對(duì)象并有一個(gè)指向setOrderDAO()的屬性。orderDAO bean將居于這個(gè)屬性中,orderDAO bean是我們的和持久層交流的DAO對(duì)象。
還有一個(gè)關(guān)于Spring和bean要注意的是bean能以?xún)煞N模式工作。這兩種模式被定義為singleton和prototype。一個(gè)bean默認(rèn)的模式是singleton,意味著一個(gè)共享的bean的實(shí)例將被管理。這是用于無(wú)狀態(tài)操作--像一個(gè)無(wú)狀態(tài)會(huì)話(huà)bean將提供的那樣。當(dāng)bean由Spring提供時(shí),prototype模式允許創(chuàng)建bean的新實(shí)例。你應(yīng)當(dāng)只有在每一個(gè)用戶(hù)都需要他們自己的bean的拷貝時(shí)才使用prototype模式。