最近工作中涉及到一些將其他項(xiàng)目組的應(yīng)用整合到我們平臺(tái)上的事情。剛好那個(gè)項(xiàng)目是base在Appfuse提供的框架基礎(chǔ)上開(kāi)發(fā)的。使用了Spring2.0 + Struts2.0 + Ibatis的框架。趁此機(jī)會(huì)把這幾個(gè)外面現(xiàn)在比較流行的東西又好好看了看。現(xiàn)在寫(xiě)個(gè)總結(jié)。也希望能便于以后的參考。好了,元?dú)w正傳,開(kāi)始我們的SSI之旅。 我們還是從代碼講起。這樣也便于我們理解。否則High Level的東西說(shuō)了一通到最后也不知道都說(shuō)明了什么。 先看幾段代碼: Spring DataSoure: <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxActive" value="${jdbc.maxActive}"/> <property name="maxIdle" value="${jdbc.maxIdle}"/> <property name="maxWait" value="${jdbc.maxWait}"/> <property name="defaultAutoCommit" value="true"/> <property name="removeAbandoned" value="true"/> <property name="removeAbandonedTimeout" value="60"/> <!-- 以下配置用于開(kāi)發(fā)時(shí)追蹤沒(méi)有釋放數(shù)據(jù)庫(kù)連接的代碼,部署時(shí)應(yīng)刪除 --> <property name="logAbandoned" value="true"/> </bean> 這里我們使用dbcp連接池。這里就不多說(shuō)了。 Spring AOP Configuration: <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource"> <ref bean="dataSource"/> </property> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <!-- the transactional semantics... --> <tx:attributes> <!-- all methods starting with 'get' are read-only --> <tx:method name="get*" read-only="true" /> <!-- other methods use the default transaction settings (see below) --> <tx:method name="*" rollback-for="Exception" /> </tx:attributes> </tx:advice>
<aop:config> <aop:pointcut id="serviceOperation" expression="execution(* com.ibm.magis..service.*Manager.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" /> </aop:config> 這里就和我們以前用的Spring就不一樣了。這里我們使用的是AspectJ 的切面事務(wù)的統(tǒng)一控制。 Spring的官方文檔說(shuō):“如果你選擇使用Spring AOP,那么你可以選擇@AspectJ或者XML風(fēng)格??偟膩?lái)說(shuō),如果你使用Java 5,我們建議使用@AspectJ風(fēng)格。”當(dāng)然項(xiàng)目中使用的是JDK1.5 所以他使用了這樣的聲明方式。 回頭看一下我們以前的方法: <bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"> <ref bean="transactionManager" /> </property> <property name="transactionAttributes"> <props> <prop key="save*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="remove*">PROPAGATION_REQUIRED,-Exception </prop> <prop key="update*">PROPAGATION_REQUIRED,-Exception </prop> <prop key="incress*">PROPAGATION_REQUIRED,-Exception </prop> <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean> 兩者相比較而言還是AspectJ的這種風(fēng)格比較好。而且我們可以方邊在Spring中定義我們自己的切面。例如日志的記錄、權(quán)限的檢查等等。 <aop:config> <aop:aspect id="objectACLAspectU" ref="objectACLAdviceU"> <aop:pointcut id="objectRemovePcU" expression="execution(* com.ibm.magis.data.instance.service.OinstanceManager.remove(..)) and args(objectId,instanceId)"/> </aop:aspect> </aop:config> <bean id="objectACLAdviceU" class="com.ibm.magis.acl.advice.ObjectACLUsingAdvice"> <property name="oinstanceManager" ref="oinstanceManager"/> <property name="objectACLManager" ref="objectACLManager"/> </bean> 經(jīng)過(guò)簡(jiǎn)單的配置在加上一個(gè)簡(jiǎn)單的實(shí)現(xiàn)類就可以完成一些復(fù)雜的切面控制的代碼了。 看完上面Spring2.0的AOP后。在看一個(gè)配置文件: <beans default-autowire="byName" default-lazy-init="true"> <bean id="objectACLDao" class="com.ibm.magis.acl.dao.ibatis.PObjectACLDaoImpl" /> </beans> 注意這個(gè)屬性default-lazy-init. 如果設(shè)置為true 則表明Spring 的IOC容器使用Lazy-load的方式進(jìn)行加載。這種懶加載的方式可從某種情況下提高啟動(dòng)的速度。但是也會(huì)有一個(gè)問(wèn)題哦??赡懿粫?huì)馬上發(fā)現(xiàn)配置錯(cuò)誤的bean. 還有一個(gè)屬性:default-autowire="byName" 設(shè)置Spring的自動(dòng)裝配方式。autowire的方便之處在減少或者消除屬性或構(gòu)造器參數(shù)的設(shè)置,這樣可以給我們的配置文件減減肥! 載至Spring官方文檔
這也是一個(gè)不錯(cuò)的地方??梢允∪ノ覀兒芏嗟胤脚渲玫娘@示聲明。 我們可以看一下Struts2.0的使用吧。個(gè)人認(rèn)為其實(shí)Struts2.0就是完全照搬的webwork的。沒(méi)有多少自己的心意。 具體的配置就不多說(shuō)了。主要是看看下面這個(gè)配置文件: <constant name="struts.i18n.encoding" value="UTF-8"/> <constant name="struts.action.extension" value="action"/> <constant name="struts.objectFactory" value="spring"/> 注意<constant name="struts.objectFactory" value="spring"/> 這里它將框架常量struts.objectFactory覆蓋了,設(shè)置為”spring”,其實(shí)這里是使用了縮寫(xiě),我們可以寫(xiě)全稱:org.apache.struts2.spring.StrutsSpringObjectFactory。這個(gè)縮寫(xiě)的”spring”是和bean配置中的name屬性相對(duì)應(yīng)的。默認(rèn)情況下所有由框架創(chuàng)建的對(duì)象都是由ObjectFactory實(shí)例化的,ObjectFactory提供了與其它IoC容器如Spring、Pico等集成的方法。覆蓋這個(gè)ObjectFactory的類必須繼承ObjectFactory類或者它的任何子類,并且要帶有一個(gè)不帶參數(shù)的構(gòu)造方法。在這里我們用org.apache.struts2.spring.StrutsSpringObjectFactory代替了默認(rèn)的ObjectFactory。 此外,上面我們說(shuō)了,如果action不是使用Spring ObjectFactory創(chuàng)建的話,插件提供了兩個(gè)攔截器來(lái)自動(dòng)裝配action,默認(rèn)情況下框架使用的自動(dòng)裝配策略是name,也就是說(shuō)框架會(huì)去Spring中尋找與action屬性名字相同的bean,可選的裝配策略還有:type、auto、constructor,我們可以通過(guò)常量struts.objectFactory.spring.autoWire來(lái)進(jìn)行設(shè)置。 這樣的話,我們就可以在Action中使用Spring IOC中注入的Bean了。其實(shí)這是webwork早有的擴(kuò)展包里的功能。呵呵。換成strut2.0了還是得說(shuō)一下。 有了上面的配置文件我們就可以把Spring2.0 和 struts2.0 結(jié)合起來(lái)了。 看看IBatis 的配置文件: <!-- SqlMap setup for iBATIS Database Layer --> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation"> <value>classpath:/sql-map-config.xml</value> </property> <property name="dataSource" ref="dataSource"/> </bean> 其實(shí)配置這個(gè)sqlMapClient在Spring中也是眾所周知的事情了。有了ByName的自動(dòng)裝配功能。我們也不需要在各個(gè)DAO中顯示的ref 這個(gè)bean 了。 具體Ibatis的使用請(qǐng)參考 Ibatis官方網(wǎng)站:http://ibatis. from:http://www./anwenhao/archive/2007/12/29/171610.html |
|