Spring 要點??
1.DTD
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN""http://www.springframework.org/dtd/spring-beans-2.0.dtd">
?? 以上是Spring 2.0的標準DTD,相比之下不是很喜歡用schema xsd文件式的定義,一大堆太長了,只有真正要使用Spring定義的Schema如TX,AOP 時才使用Schema。
2.default-lazy-init
???? Spring的lazy-init,可以使單元測試與集成測試時的速度大大加快,不過要留意一些類比如XFire導出WebService的定義,還有Spring MVC的xx-servlet.xml文件,都不能定為lay-init,否則會吃大虧。
3.PropertyOverrideConfigurer
??? 不同于PropertyPlaceholderConfigurer 替換context文件中的變量,PropertyOverrideConfigurer是在ApplicationContext 初始化的最后,強行將某些Bean的某些屬性,替換成它的properties文件里的值。
??? 比如生產環境的jdbc.properties里定義了jdbc連接為Oracle,并通過PlaceholderConfigurer設置到<bean id="dataSource"> 里,在測試時再載入下面的applicationContex-test.xml文件,就能透明的將配置更改為嵌入式數據庫。
applicationContext-test.xml: 定義載入的properties。
<bean id="testPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"> <property name="location" value="classpath:spring/test/jdbc.properties"/> </bean>
spring/test/jdbc.properties: 將ApplicationContext 中id為dataSource的bean的url屬性改為使用hsqldb。
dataSource.url=jdbc:hsqldb:res:default-db
4. Spring 2.0的schema簡寫
?Spring 2.0開始推進了一系列的簡寫法,從僵硬的<bean id="xx" class="xxxx.xxx.xxx">,轉為<aop:xxxx>這樣的形式。
?完整的schema列表見參考手冊附錄A: http://www.redsaga.com/spring_ref/2.0/html/xsd-config.html
?另外,附錄B還提供了自行開發schema的方式。手冊里宣稱,普通應用項目團隊要開發schema有點麻煩,但呼吁各開源項目團隊開發都各自的schema,共同簡化配置文件。
?其中有一種可能是最容意使用的默認schema是p,推進<propertity>節點寫法的進一步簡化。
<bean> <property name="foo" value="foovalue"> <property name="fooBean" ref="fooBean"/> </bean> <!-- 簡寫為 --> <bean p:foo="foovalue" p:fooBean-ref="fooBean"/>?
5.default-merge
?? 從Spring 2.0M2開始,beans支持default-merge= "true" 的定義,子類不需要重新定義父類的List型屬性中已定義過的內容。
? 在聲明式事務體系下,一般會定義一個baseTxService基類
<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="update*">PROPAGATION_REQUIRED</prop> <prop key="remove*">PROPAGATION_REQUIRED</prop> </props> </property> </bean>
?? 可以在beans統一定義default-merge= true,也可以每個bean定義,則子類的transactionAtttributes只須定義子類新增的部分,無須再定義get*,save*等。
?? 不過Spring2.0已采用新的AOP寫法,此方法的重要性下降。
<beans default-merge="true"> <bean id="orderManager" parent="baseTxService"> <property name="target"> <bean class="org.springside.bookstore.service.OrderManager"/> </property> <property name="transactionAttributes"> <props> <prop key="shipOrder">PROPAGATION_REQUIRED</prop> </props> </property> </bean> </beans>
6.IMPORT
??? ?如何組織ApplicationContext文件,決定了聲明式編程會不會差一步變成配置地獄。
??? ?SpringSide建議:為了單元測試,ApplicationContext文件盡量放ClassPath 而不是WEB-INF 目錄。
??? ?盡量使用<Import> 幫助以模塊為單元組織ApplicationContext文件。
??? 如根目錄的 /applicationContext.xml 和 springmvc-servlet.xml,都只定義一些公共的東西,然后以如下方式include模塊里的applicationContext:
<import resource="classpath:org/springside/bookstore/admin/applicationContext-manager.xml"/>
7.IntrospectorCleanupListener
? 避免Struts,Quartz的內存泄露導致ClassLoader不能加載。詳細見Spring的API DOC文檔:
? ?<listener> ??????? <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> ??? </listener>