Spring筆記

  本文檔適用於使用過Spring的開發者,該文章有助於他們重新梳理一下對Spring的認識。
       這篇文章是本人在項目開發中使用Spring的總結,這裏只是歸納了我們在開發中經常要用到的Spring的特性,Spring的其他特性或者使用起來比較複雜,或者很少有機會在實際開發中使用將不再本文中做介紹。
      
一、背景,爲什麼我們需要Spring?
Martin Flower提出了IoC(Inversion of Control),反轉的是什麼樣的控制?
以前我們在一個java對象中要使用另外一個java對象,即定義兩個java bean之間的依賴關係,通常通過以下三種方式建立:
(1) Bean自己實例化另外一個bean。
(2) 在bean的構造函數中指定依賴關係。
(3) 使用類似service locator模式來獲得另外一個bean。
這三種方式都是由bean自己自主控制依賴關係。
現 在我們通過IoC容器來創建bean並注入它們之間的依賴關係。這樣對象的創建和依賴關係的定義就由專門的IoC容器來實現,而不是由對象本身。這樣就是 我們所說的控制的翻轉。好處:bean自己不再負責對象的依賴關係,從而降低對象之間的耦合。同時讓開發者把精力放在業務邏輯的編寫上。
 
這 種控制翻轉更確切的說是Dependency Injection(依賴注入),依賴關係通過容器來注入實現的。我們通過接口的方式實現它,這也符合DIP的原則,即Dependency Inversion Principle(依賴倒轉原則:面對對象編程的基本原則)。
 
spring最新版本:
Spring Framework 2.0 (current production version 2.0.3)
我們公司大多數使用的
Spring Framework 1.2 (current production version 1.2.8)
       Spring就是一個輕量級的IoC容器。IoC容器最主要的功能就是幫助我們管理對象,並建立他們的依賴關係。
 
 
 
二、Spring框架介紹
Core封裝包是框架最基礎的部分,提供IoC和依賴注入特性。
DAO提供了JDBC的抽象和封裝,方便我們使用JDBC的方式訪問數據庫,同時提供了聲明式事務管理的功能。
ORM提供了常用的ORM Mapping API(JPA, JDO, Hibernate, iBatis.)的集成。我們公司目前採用Spring提供的ibatis集成。
AOP提供了面向方面的編程實現,讓我們可以方便的定義方法攔截器和切點。
WEB提供了針對web層開發的集成特性。
 
三、Core
org.springframework.beans 和org.springframework.context是spring IoC容器的基礎。
org.springframework.beans.factory.BeanFactory初始化和配置Bean,裝配它們之間的依賴關係。
ApplicationContext 是擴展了BeanFactory ,提供了更多的功能,在使用中Spring作者推薦是使用ApplicationContext。
幾個重要的知識點:
(1) spring注入的方式:Setter注入和構造器注入。如果採用Setter方法注入,別忘了在類定義的時候加上setter方法,這一點開發者常常會忘掉,導致NullPointerException。
(2)    自動裝配:Spring提供多種自動裝配的功能,其中byName是最好用、最常用的。可以大大簡化bean的定義。例子
<beans default-autowire="byName">
比如我們定義了一個bean 類,它包含了master屬性,並且含有setMaster方法,那麼spring會自動在IoC容器中尋找名爲master的bean,然後調用setMaster將master對象賦值給master。
 
(3)Bean的作用域
Singleton
Spring容器只存在一個共享的bean實例,默認的配置。
<bean id="example" class="com.yz.bean.Example"/>
Prototype
每次對bean的請求都會創建一個新的bean實例。
<bean id="example" class="com.yz.bean.Example" singleton=”false”/>
 
兩者如何選擇?原則:所有有狀態的bean都使用Prototype作用域,而對無狀態的bean則應該使用singleton作用域。
 
(4) 熟悉Spring的配置文件xml中bean的定義,有助於我們靈活地定義bean。
Bean的定義的格式基本如下:
<bean id="example" class="com.yz.bean.Example"/>
id唯一標識該bean,要使用某個bean,只需在容器中通過id獲得之,就可以獲得它的一個實例。
 
Bean的屬性定義如:<properyt name=””>
 
其屬性值可以爲:
l         其它bean:
ref bean=
ref local=
l         集合
<list> <set> <map> <props>
l         數字,字符串。
 
 
(6) bean定義中的繼承關係,使用這種繼承關係同樣可以簡化bean的定義,實際開發中經常被使用。
如果你希望你的java bean的實例能繼承另外一個java bean的配置信息。那麼你在定義該bean的時候要使用parent屬性。
<bean id="childExample" class="com.yz.bean.ChildExample" parent="example"></bean>
儘管這兩個bean實際上沒有類的繼承關係,也可以使用parent屬性。這種parent屬性的方式實際上提供了模板的形式。
 
(7)  PropertyPlaceholderConfigure
用途:將spring中分佈在不同的xml文件的一些屬性值統一到一個文件來維護。這樣可以提高我們程序的維護性,我們在實際開發中經常使用它。
      
 
   <bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="location" value="/com/yz/bean/common.properties"/>
    </bean>
    <bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
 
(8) 資源讀取。
       Spring來讀取配置文件是按照以下的規則進行的:
前綴
例子
說明
classpath:
classpath:com/myapp/config.xml
classpath中載入。
file:
file:/data/config.xml
從文件系統載入。
http:
http://myserver/logo.png
作爲URL載入。
(none)
/data/config.xml
取決於當前的ApplicationContext
      
 
四、AOP
1、背景
AOP(Aspect-Oriented Programming)是對Object-Oriented Programming (OOP)的補充,
OOP通過類的繼承實現功能的重用,如果某個功能是多個不同類型的類都需要具有的話,OOP就解決不了這個問題,這樣就需要AOP來幫助我們
AOP通過切面來達到我們的實現可以跨越不同對象和類型。
Spring中的AOP主要用於:
(1)       提供聲明式企業服務,比如聲明的事務管理
(2)       允許使用者實現定製的aspects, 這是對OOP的補充。
 
2、概念
Joinpoint(連接點):程序執行過程中的某個特定的點。比如某個方法的調用或者異常。
通常我們希望在這個joinpoint上執行某個特殊的功能。Spring的AOP目前只支持連接點爲方法的調用。
Aspect(切面):橫切多個對象的關注點的模塊化。比如事務處理,我們有多個對象都需要實現事務處理的功能,Aspect就是我們將多個對象共同關注的功能抽出獨立出來。
Advice(通知):在某個特定的Joinpoint上切面執行的動作。通常我們通過攔截器interceptor或者advisor來實現,
Pointcut(切入點):符合某種規則的連接點。
目標對象:被代理的對象。
AOP代理:AOP框架創建的對象,用來代理我們的目標對象。
 
Spring缺省使用j2se動態代理來作爲AOP的代理,如果要代理的類沒有繼承任何接口,spring使用CGLIB代理。Spring使用org.springframework.aop.framework.ProxyFactoryBean來產生代理對象。
 
3、簡化代理定義
在實際開發中常常有許多相似的代理定義,那麼我們可以創建一個模板bean,這個bean本身不會初始化,每個需要創建的代理都定義爲這個bean的子bean。
 
 
五、spring的DAO
1、JDBC封裝包
涉及spring的包:core, dataSource, object, and support。
org.springframework.jdbc.core由JdbcTemplate類以及相關的回調接口組成。
org.springframework.jdbc.datasource提供了簡化DataSource訪問的工具類。
org.springframework.jdbc.object提供了一些處理查詢、更新、存儲過程的類。
org.springframework.jdbc.support提供了SQLException的轉換類和相關的工具類。
Spring將所有jdbc處理中拋出的異常轉換爲spring dao包中定義的異常,這些異常是unchecked exception,我們可以對這些異常有選擇的捕獲。這也是Spring提供的一個很重要的特性。
看例子:
2、DataSource可以JNDI,或者apache提供的dbcp,或者spring自帶的DriverManagerDataSource。
3、需要了解的知識:
(1)    JdbcTemplate是線程安全的。
(2)   我 們如果要獲得connection,需要調用DataSourceUtils.getConncetion(),這個類會把SQLException的異 常轉換爲spring的unchecked Exception,並且如果我們使用DataSourceTransactionManager的話,該connection會綁定到當前線程中。
JdbcTemplate就是通過這種方式獲得數據庫連接的。
 
六、spring的ORM
Spring的ORM提供了對常用ORM Mapping工具的封裝,包括Hibernate、JDO、ibatis
等,ibatis由於使用和jdbc sql的訪問方式相似,同時sql語句可控,便於DBA優化,所以深受普遍歡迎。
 
 
 
批量操作:
public class SqlMapAccountDao extends SqlMapClientDaoSupport implements AccountDao {
 
    public void insertAccount(Account account) throws DataAccessException {
        getSqlMapClientTemplate().execute(new SqlMapClientCallback() {
            public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
                executor.startBatch();
                executor.update("insertAccount", account);
                executor.update("insertAddress", account.getAddress());
                executor.executeBatch();
            }
        });
    }
}
 
七、Spring的事務管理
1、全局事務和本地事務
如果我們的應用涉及到多個事務性資源的參與(比如多個數據庫),我們就需要使用全局事務,全局事務是由應用服務器管理的,我們它使用JTA。
本地事務是指只涉及單個事務資源(比如一臺數據庫)。應用服務器不涉及事務管理,不能跨越多個資源。
 
2、spring的事務
    Spring使用PlatformTransactionManager來管理事務。定義如下:
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 
3、聲明式事務管理
    聲明式事務管理,開發者不用編寫事務代碼就可以實現事務處理。
    Spring的事務管理是通過spring AOP來實現的。
    我 們通過TransactionProxyFactoryBean設置Spring事務代理,然後將目標對象包裝在事務代理中。當定義 TransactionProxyFactoryBean時,必須提供一個相關的PlatformTransactionManager的引用和事務屬 性。
<bean id="petStoreTarget">
</bean>
<bean id="petStore"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager"><ref bean="transactionManager"/></property>
    <property name="target"><ref bean="petStoreTarget"/></property>
    <property name="transactionAttributes">
        <props>
            <prop key="insert*">PROPAGATION_REQUIRED,-MyCheckedException</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
        </props>
    </property>
</bean>
 
4、編程式事務管理
Object result = transactionTemplate.execute(new TransactionCallback() {
 
    public Object doInTransaction(TransactionStatus status) {
        updateOperation1();
 
        return resultOfUpdateOperation2();
    }
 
});
 
Spring參考文獻:
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章