程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Spring框架基礎知識圖文講解教程

Spring框架基礎知識圖文講解教程

編輯:關於JAVA
 

Spring框架由Rod Johnson開發,2004年發布了Spring框架的第一版。Spring是一個從實際開發中抽取出來的框架,因此它完成了大量開發中的通用步驟,留給開發者的僅僅是與特定應用相關的部分,從而大大提高了企業應用的開發效率。

Spring總結起來優點如下:

  • 低侵入式設計,代碼的污染極低

  • 獨立於各種應用服務器,基於Spring框架的應用,可以真正實現Write Once,Run Anywhere的承諾

  • Spring的IoC容器降低了業務對象替換的復雜性,提高了組件之間的解耦

  • Spring的AOP支持允許將一些通用任務如安全、事務、日志等進行集中式管理,從而提供了更好的復用

  • Spring的ORM和DAO提供了與第三方持久層框架的良好整合,並簡化了底層的數據庫訪問

  • Spring的高度開放性,並不強制應用完全依賴於Spring,開發者可自由選用Spring框架的部分或全部

Spring框架的組成結構圖如下所示

spring-overview

Spring的核心機制

管理Bean

程序主要是通過Spring容器來訪問容器中的Bean,ApplicationContext是Spring容器最常用的接口,該接口有如下兩個實現類

  • ClassPathXmlApplicationContext: 從類加載路徑下搜索配置文件,並根據配置文件來創建Spring容器

  • FileSystemXmlApplicationContext: 從文件系統的相對路徑或絕對路徑下去搜索配置文件,並根據配置文件來創建Spring容器

1
2
3
4
5
6
7
public class BeanTest{
    public static void main(String args[]) throws Exception{
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
        Person p = ctx.getBean("person", Person.class);
        p.say();
    }
}

Eclipse使用Spring

在Eclipse等IDE工具中,用戶可以自建User Library,然後把Spring的Jar包都放入其中,當然也可以將Jar包直接放在項目的/WEB-INF/lib目錄下,但是如果使用User Library,在項目發布時,需要將用戶庫所引用的Jar文件隨應用一起發布,就是將User Library所使用的Jar復制到/WEB-INF/lib目錄下,這是因為對於一個Web應用,Eclipse部署Web應用時不會將用戶庫的Jar文件復制到/WEB-INF/lib下,需要手動復制。

依賴注入

Spring框架的核心功能有兩個

  • Spring容器作為超級大工廠,負責創建、管理所有的Java對象,這些Java對象被稱為Bean

  • Spring容器管理容器中Bean之間的依賴關系,Spring使用一種被稱為“依賴注入”的方式來管理Bean之間的依賴關系

使用依賴注入,不僅可以為Bean注入普通的屬性值,還可以注入其他Bean的引用。依賴注入是一種優秀的解耦方式,其可以讓Bean以配置文件組織在一起,而不是以硬編碼的方式耦合在一起。

理解依賴注入

Rod Johnson是第一個高度重視以配置文件來管理Java實例的協作關系的人,他給這種方式起了一個名字:控制反轉(Inverse of Control,IoC)。後來Martine Fowler為這種方式起了另一個名稱:依賴注入(Dependency Injection),因此不管是依賴注入,還是控制反轉,其含義完全相同。當某個Java對象(調用者)需要調用另一個Java對象(被依賴對象)的方法時,在傳統模式下通常有兩種做法

  1. 原始做法: 調用者主動創建被依賴對象,然後再調用被依賴對象的方法

  2. 簡單工廠模式: 調用者先找到被依賴對象的工廠,然後主動通過工廠去獲取被依賴對象,最後再調用被依賴對象的方法

注意上面的主動二字,這必然會導致調用者與被依賴對象實現類的硬編碼耦合,非常不利於項目升級的維護。使用Spring框架之後,調用者無需主動獲取被依賴對象,調用者只要被動接受Spring容器為調用者的成員變量賦值即可,由此可見,使用Spring後,調用者獲取被依賴對象的方式由原來的主動獲取,變成了被動接受——所以Rod Johnson稱之為控制反轉。

另外從Spring容器的角度來看,Spring容器負責將被依賴對象賦值給調用者的成員變量——相當於為調用者注入它依賴的實例,因此Martine Fowler稱之為依賴注入。

設值注入

設值注入是指IoC容器通過成員變量的setter方法來注入被依賴對象。這種注入方式簡單、直觀,因而在Spring的依賴注入裡大量使用。

構造注入

利用構造器來設置依賴關系的方式,被稱為構造注入。通俗來說,就是驅動Spring在底層以反射方式執行帶指定參數的構造器,當執行帶參數的構造器時,就可利用構造器參數對成員變量執行初始化——這就是構造注入的本質。

兩種注入方式的對比

設值注入有如下優點

  • 與傳統的JavaBean的寫法更相似,程序開發人員更容易理解、接受。通過setter方法設定依賴關系顯得更加直觀、自然

  • 對於復雜的依賴關系,如果采用構造注入,會導致構造器過於臃腫,難以閱讀。Spring在創建Bean實例時,需要同時實例化其依賴的全部實例,因而導致性能下降。而使用設值注入,則能避免這些問題。

  • 尤其在某些成員變量可選的情況下,多參數的構造器更加笨重

構造注入優勢如下

  • 構造注入可以在構造器中決定依賴關系的注入順序,優先依賴的優先注入

  • 對於依賴關系無需變化的Bean,構造注入更有用處。因為沒有setter方法,所有的依賴關系全部在構造器內設定,無須擔心後續的代碼對依賴關系產生破壞

  • 依賴關系只能在構造器中設定,則只有組件的創建者才能改變組件的依賴關系,對組件的調用者而言,組件內部的依賴關系完全透明,更符合高內聚的原則

Notes
建議采用設值注入為主,構造注入為輔的注入策略。對於依賴關系無須變化的注入,盡量采用構造注入;而其他依賴關系的注入,則考慮采用設值注入。

Spring容器中的Bean

對於開發者來說,開發者使用Spring框架主要是做兩件事:①開發Bean;②配置Bean。對於Spring框架來說,它要做的就是根據配置文件來創建Bean實例,並調用Bean實例的方法完成“依賴注入”——這就是所謂IoC的本質。

容器中Bean的作用域

當通過Spring容器創建一個Bean實例時,不僅可以完成Bean實例的實例化,還可以為Bean指定特定的作用域。Spring支持如下五種作用域

  1. singleton: 單例模式,在整個Spring IoC容器中,singleton作用域的Bean將只生成一個實例

  2. prototype: 每次通過容器的getBean()方法獲取prototype作用域的Bean時,都將產生一個新的Bean實例

  3. request: 對於一次HTTP請求,request作用域的Bean將只生成一個實例,這意味著,在同一次HTTP請求內,程序每次請求該Bean,得到的總是同一個實例。只有在Web應用中使用Spring時,該作用域才真正有效

  4. 對於一次HTTP會話,session作用域的Bean將只生成一個實例,這意味著,在同一次HTTP會話內,程序每次請求該Bean,得到的總是同一個實例。只有在Web應用中使用Spring時,該作用域才真正有效

  5. global session: 每個全局的HTTP Session對應一個Bean實例。在典型的情況下,僅在使用portlet context的時候有效,同樣只在Web應用中有效

如果不指定Bean的作用域,Spring默認使用singleton作用域。prototype作用域的Bean的創建、銷毀代價比較大。而singleton作用域的Bean實例一旦創建成果,就可以重復使用。因此,應該盡量避免將Bean設置成prototype作用域。

使用自動裝配注入合作者Bean

Spring能自動裝配Bean與Bean之間的依賴關系,即無須使用ref顯式指定依賴Bean,而是由Spring容器檢查XML配置文件內容,根據某種規則,為調用者Bean注入被依賴的Bean。
Spring自動裝配可通過<beans/>元素的default-autowire屬性指定,該屬性對配置文件中所有的Bean起作用;也可通過對<bean/>元素的autowire屬性指定,該屬性只對該Bean起作用。

autowire和default-autowire可以接受如下值

  • no: 不使用自動裝配。Bean依賴必須通過ref元素定義。這是默認配置,在較大的部署環境中不鼓勵改變這個配置,顯式配置合作者能夠得到更清晰的依賴關系

  • byName: 根據setter方法名進行自動裝配。Spring容器查找容器中全部Bean,找出其id與setter方法名去掉set前綴,並小寫首字母後同名的Bean來完成注入。如果沒有找到匹配的Bean實例,則Spring不會進行任何注入

  • byType: 根據setter方法的形參類型來自動裝配。Spring容器查找容器中的全部Bean,如果正好有一個Bean類型與setter方法的形參類型匹配,就自動注入這個Bean;如果找到多個這樣的Bean,就拋出一個異常;如果沒有找到這樣的Bean,則什麼都不會發生,setter方法不會被調用

  • constructor: 與byType類似,區別是用於自動匹配構造器的參數。如果容器不能恰好找到一個與構造器參數類型匹配的Bean,則會拋出一個異常

  • autodetect: Spring容器根據Bean內部結構,自行決定使用constructor或byType策略。如果找到一個默認的構造函數,那麼就會應用byType策略

當一個Bean既使用自動裝配依賴,又使用ref顯式指定依賴時,則顯式指定的依賴覆蓋自動裝配依賴;對於大型的應用,不鼓勵使用自動裝配。雖然使用自動裝配可減少配置文件的工作量,但大大將死了依賴關系的清晰性和透明性。依賴關系的裝配依賴於源文件的屬性名和屬性類型,導致Bean與Bean之間的耦合降低到代碼層次,不利於高層次解耦

1
2
3
4
<!--通過設置可以將Bean排除在自動裝配之外-->
<bean id="" autowire-candidate="false"/>
<!--除此之外,還可以在beans元素中指定,支持模式字符串,如下所有以abc結尾的Bean都被排除在自動裝配之外-->
<beans default-autowire-candidates="*abc"/>

創建Bean的3種方式  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved