我認為Springframewrok提供兩大核心的module: IoC Container以及Aspect-Oriented Programming,其他的module一定跟都是建立在Ioc Container之上,另外有些model則是應用AOP的概念如Tranaction以及Spring Security。
先介紹前者,IoC是Inversion of Control的縮寫,是行之有年著名的Design Pattern,不知道是當初名字似乎無法完全表達它的精隨,後來就變成大家都知道的Dependency Injection (DI),詳細的介紹官網推薦您看Martin Fowler的文章,在開發Java的時候,我們常重複使用某些class,例如xxxDAO,那麼每次用到的時候,都要new一個Instance,某個程度上這是一種DRY(Don't Repeat Yourself),導入Spring後呢,若兩個class是相依的,例如某個物件需要呼叫DAO物件的方法來取的資料,則可以透過Spring Bean Container來協助管理物件間的相依性,也就是說我們可以在Spring Bean Container中註冊一個DAO物件(在Spring中稱作Bean)以及其有相依性的物件並設定他們之間的相依性,那麼我們就可以依賴Spring Bean Container來幫助我們管理這些相依性,不需要在程式碼中每次都new xxxDAO()。
Spring Bean Configuration File就是定義在Container中各個Bean相關屬性以及相依性的設定檔,格式是XML,初始化Bean Container時所需要的檔案,接下就來介紹用STS來協助我們產生設定檔,當然也可以用純文字檔自己hardcode,但用STS可以幫忙帶出相關XML Schema及Namespace,同時也可以避免標籤拼錯字以及用快速鍵可以提示相關屬性,方便很多,以下就以Datasource以及DAO Class為例。
首先New->Spring Bean Configuration File->取名service.xml並存放在WEB-INF下新增一個springconfig資料夾下>Next
將以下module的namespace加入,另建議選擇沒有版本的.xsd檔,以避免未來使用不同版本的時候,解析XML可能出現錯誤。
AOP、beans、cache、context、jdbc、lang、task、tx、util後Finish。
Datasource部分我選用BoneCP,號稱結合Apache DBCP以及C3P0,在其官網上有比較與DBCP performance差異,請於pom.xml加入以下code
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp</artifactId>
<version>0.8.0.RELEASE</version>
</dependency>
接著在剛建立的service.xml新增一個bean,code如下
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="idleConnectionTestPeriodInMinutes" value="60" />
<property name="idleMaxAgeInMinutes" value="240" />
<property name="maxConnectionsPerPartition" value="30" />
<property name="minConnectionsPerPartition" value="10" />
<property name="partitionCount" value="3" />
<property name="acquireIncrement" value="5" />
<property name="statementsCacheSize" value="100" />
<property name="releaseHelperThreads" value="3" />
</bean>
在bean標籤下用property來指定設定值,這樣的形式稱為Setter-based Injection,name就是對應物件裡屬性,value是直接指定值,有另外的標籤屬性ref,代表設定值可以參照到其他的bean,另外destory-method指的是當這個bean生命週期結束其要執行什麼工作,以連結Database為例的話,就是close連結囉。
接著於tw.blogger.springtech.springmvc.model.dao package下新增MyDAO class,code如下
package tw.blogger.springtech.springmvc.model.dao;
import com.jolbox.bonecp.BoneCPDataSource;
public class MyDAO {
private BoneCPDataSource dataSource;
public MyDAO(BoneCPDataSource dataSource){
this.dataSource=dataSource;
}
}
再來我們要設定把BoneCPDataSource注入MyDAO,回到service.xml並加入以下code
<bean id="myDAO" class="tw.blogger.springtech.springmvc.model.dao.MyDAO">
<constructor-arg ref="dataSource"/>
</bean>
這種方式稱作Constructor-based Injection,如果constructor有多個參數,則可用標籤屬性"index",指定多個參數,第一個參數從0開始如:
<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg index="0" ref="beanDemo"/>
<constructor-arg index="1" value="42"/>
</bean>
放上截圖作為今日的句點,AOP部分到Spring Security的時候再簡單說明它用在哪裡,明日應開可以寫出第一個Spring MVC Hello! World