反思Spring:由RubyonRails想到的
眾所周知,RoR里面的指導原則有:
第一條是較小的軟件,這意味著你編寫較少的程序行。程序小就能加速開發,錯誤也較少,使得程序較容易理解、維護和增強。對編寫較小程序做出貢獻的Ruby的一個特性就是它假設該架構本身能夠并應該處理元數據.
第二條是對配置的協定原理,這意味著Rails不用配置文件,而是依靠一些簡單的編程協定,讓它通過利用應用程序已有的信息和在運行的數據庫,解決它需要知道什么這個問題。
Spring一個非常靈活的一個框架,靈活的同時也造成了一定的復雜性。我個人眼中的spring應該從RoR學到的東西應該有:不用寫一行xml語句就可以配置好AOP常規的事務管理,約定高于配置。
當前spring支持的事務管理配置,大體有以下兩種配置方式,為了方便舉例子,所以借用了javaEE技術專家"江南白衣"的兩段代碼
(1)、spring2.0版本支持的事務管理
代碼:
(2)、 spring2.0開始支持事務管理的新配置
代碼
上面的二段配置文件代碼是常用的spring事務管理配置.
看完上面的二段代碼的配置,和Ruby on Rails沒有一行配置的ActiveRecord相比差太遠,相對麻煩拖拉,沒有辦法,暫時spring實現中事務管理主要也只是這兩種方法。
使用spring通常會與hibernate/ibatis集成作數據訪問層,這也是大多java開發人員常用字的技術框架.下面如spring和hibernate結合做數據訪問層,暫時不討論有泛型存在的情況,只是簡單舉一個例子把事務管理放在數據訪問層。下面說出我自己心中理想的spring事務管理:
約定高于配置。首先規定,對于query,list,show,get,find等開頭的方法采用PROPAGATION_REQUIRED,readOnly級的事務定義;而對于set,save,update,remove,delete等開頭的方法采用PROPAGATION_REQUIRED級的事務定義,基本上能滿足大部分開發的需要。然后只要在需要事務管理配置的類的前加一句元數據即可,例如spring針對hibernate3開發的@TransactionAop(hibernate3),類似的有@TransactionAop(hibernate2)、@TransactionAop(ibatis)、@TransactionAop(jdo)之類元數據的
舉一個例子看一段代碼,其中UserDAO是一個接口,大家都應該看得出來,只加了一行的元數據@TransactionAop(hibernate3)就可以使得這一個UserDAHibernate類有事務管理的功能,因為它命名的方法符合spring的約定。(當然,這不是真的,spring中也沒有這一個功能,這只是我個人一點想法提出來而已)
代碼
spring的事務定義很靈活很廣,定義七種的傳播行為和五種的隔離常量,但用得比較多還是PROPAGATION_REQUIRED和PROPAGATION_REQUIRED,readOnly,所以我提出上面所述的一點假想,可以簡便開發。
簡單就是美。
第一條是較小的軟件,這意味著你編寫較少的程序行。程序小就能加速開發,錯誤也較少,使得程序較容易理解、維護和增強。對編寫較小程序做出貢獻的Ruby的一個特性就是它假設該架構本身能夠并應該處理元數據.
第二條是對配置的協定原理,這意味著Rails不用配置文件,而是依靠一些簡單的編程協定,讓它通過利用應用程序已有的信息和在運行的數據庫,解決它需要知道什么這個問題。
Spring一個非常靈活的一個框架,靈活的同時也造成了一定的復雜性。我個人眼中的spring應該從RoR學到的東西應該有:不用寫一行xml語句就可以配置好AOP常規的事務管理,約定高于配置。
當前spring支持的事務管理配置,大體有以下兩種配置方式,為了方便舉例子,所以借用了javaEE技術專家"江南白衣"的兩段代碼
(1)、spring2.0版本支持的事務管理
代碼:
<bean id="baseTxService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true"> <property name="transactionManager" ref="transactionManager"/> <property name="proxyTargetClass" value="true"/> <property name="transactionAttributes"> <props> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="save*">PROPAGATION_REQUIRED</prop> <prop key="remove*">PROPAGATION_REQUIRED</prop> </props> </property> <property name="preInterceptors"> <list> <ref bean="methodSecurityInterceptor"/> </list> </property> </bean> <bean id="bookManager" parent="baseTxService"> <property name="target"> <bean class="org.springside.bookstore.admin.manager.BookManager"/> </property> </bean> |
(2)、 spring2.0開始支持事務管理的新配置
代碼
<aop:config proxy-target-class="true"> <aop:advisor pointcut="execution(*yourpackagename..*Manager.*(..))" advice-ref="txAdvice"/> <aop:advisor pointcut="execution(*yourpackagename..*Manager.save(..))" advice-ref="fooAdvice"/> </aop:config><tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*"/> <tx:method name="remove*"/> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <bean id="bookManager" class="org.springside.bookstore.commons.service.BookManager"/> |
上面的二段配置文件代碼是常用的spring事務管理配置.
看完上面的二段代碼的配置,和Ruby on Rails沒有一行配置的ActiveRecord相比差太遠,相對麻煩拖拉,沒有辦法,暫時spring實現中事務管理主要也只是這兩種方法。
使用spring通常會與hibernate/ibatis集成作數據訪問層,這也是大多java開發人員常用字的技術框架.下面如spring和hibernate結合做數據訪問層,暫時不討論有泛型存在的情況,只是簡單舉一個例子把事務管理放在數據訪問層。下面說出我自己心中理想的spring事務管理:
約定高于配置。首先規定,對于query,list,show,get,find等開頭的方法采用PROPAGATION_REQUIRED,readOnly級的事務定義;而對于set,save,update,remove,delete等開頭的方法采用PROPAGATION_REQUIRED級的事務定義,基本上能滿足大部分開發的需要。然后只要在需要事務管理配置的類的前加一句元數據即可,例如spring針對hibernate3開發的@TransactionAop(hibernate3),類似的有@TransactionAop(hibernate2)、@TransactionAop(ibatis)、@TransactionAop(jdo)之類元數據的
舉一個例子看一段代碼,其中UserDAO是一個接口,大家都應該看得出來,只加了一行的元數據@TransactionAop(hibernate3)就可以使得這一個UserDAHibernate類有事務管理的功能,因為它命名的方法符合spring的約定。(當然,這不是真的,spring中也沒有這一個功能,這只是我個人一點想法提出來而已)
代碼
package org.appfuse.dao.hibernate; import java.util.List; import org.appfuse.dao.UserDAO; import org.appfuse.model.User; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; span style="color:blue;"> //假設有下面這一個類 import org.springframework.orm.hibernate3.support.annotations.TransactionAop;</span> <span style="color:blue;">@TransactionAop(hibernate3)</span> public class UserDAOHibernate extends HibernateDaoSupport implements UserDAO...{ public User getUser(Long userId) ...{ return (User)this.getHibernateTemplate().get(User.class, userId); } public List getUsers() ...{ return this.getHibernateTemplate().find("from User"); } public void removeUser(Long userId) ...{ Object user = this.getHibernateTemplate().load(User.class, userId); this.getHibernateTemplate().delete(user); } public void saveUser(User user) ...{ this.getHibernateTemplate().saveOrUpdate(user); } } |
spring的事務定義很靈活很廣,定義七種的傳播行為和五種的隔離常量,但用得比較多還是PROPAGATION_REQUIRED和PROPAGATION_REQUIRED,readOnly,所以我提出上面所述的一點假想,可以簡便開發。
簡單就是美。