0 Spring的依賴注入大體是這樣工做的:html
將對象如何構造(ID是什麼?是什麼類型?給屬性設置什麼值?給構造函數傳入什麼值?)寫入外部XML文件裏。在調用者須要調用某個類時,不自行構造該類的對象,而是從Spring容器裏拿。Spring容器會根據XML文件構造好。這樣,若是須要替換類或更改對象的屬性值,只需修改XML而不須要重編譯,實現組件級別的低耦合,而不是類級別的低耦合。java
依賴注入是Spring的基礎,DAI等許多上層模塊都依賴於它。當接觸到Spring JDBC的時候咱們會深入體會到它的Easy-to-use。git
1 Spring關鍵字:github
DI:Dependency Injection,依賴注入。依賴指的是調用關係。A調用B則A依賴於B。注入指的是A再也不new B對象,而是由Spring容器來注入B對象。spring
IoC:控制反轉,對象再也不由調用者來new,而是把new對象的任務交給Spring容器,Spring從XML中讀取對象的屬性值。數據庫
AOP:面向切面變成(區別於面向對象編程OOP)。so,切面是什麼?一些公共行爲?編程
DAI:Spring整合了針對多種數據庫的訪問方式(含JDBC、OXM等)瀏覽器
框架融合:能夠融合Hibernate和Struts框架app
解藕:爲何用了依賴注入就解藕了?框架
「神說:要有光。因而就有了光」
2 Spring下載:
源文件:springframework-4.1.6.zip
雖然下載到的壓縮包並未以src命名,但源文件確實不包含能夠直接使用的jar包,而是包含各個Spring模塊的java類源代碼。也許是須要將那些源代碼加入到用戶的項目中?活着本身編譯出JAR?。方便用戶修改Spring框架自己。目錄中提供了import-into-eclipse.sh來引導咱們將那些源代碼構建城eclipse的項目,完成這一步以後才能導入到eclipse中。
移步 https://github.com/spring-projects/spring-framework
JAR包(RELEASE發行版):springframework-4.1.6-RELEASE
Spring官網改版後,再也不直接提供JAR的下載連接。由於Spring自此只建議用MAVEN等依賴管理工具,而不是手動地複製JAR包到用戶的項目目錄,而後手動地將JAR導入爲LIBRARY。
移步 repo.spring.io/libs-release-local/org/springframework/spring/ (這個站點除了由spring地發行版,還各個模塊單獨的RELEASE,還有許多其餘資源)
3 用Demo說明如何使用Spring
a 對於像我這樣對MAVEN不甚瞭解的菜鳥,最簡單的辦法仍是把相關的JAR複製到項目裏,而後添加爲lib。Spring還須要commons-logging的庫,不然會報ClassNotFoundException。下載,解壓縮,把裏面的jar包複製到項目裏。
b 該寫的類寫好。好比:
1 package com.bean; 2 3 public abstract class Person { 4 5 String name; 6 int age; 7 8 public String getName() { 9 return name; 10 } 11 12 public int getAge() { 13 return age; 14 } 15 16 public void setAge(int age) 17 { 18 if(age>=0) this.age = age; 19 } 20 21 public void setName(String name) 22 { 23 if(name!=null) this.name=name; 24 } 25 26 public void show() 27 { 28 29 } 30 }
1 package com.bean; 2 3 public class French extends Person{ 4 5 public French() 6 { 7 } 8 public French(String name, int age) 9 { 10 setName(name); 11 setAge(age); 12 } 13 14 public void show() 15 { 16 System.out.println("French - " + name + " " + age); 17 } 18 }
1 package com.bean; 2 3 public class Chinese extends Person{ 4 5 public Chinese() 6 { 7 } 8 public Chinese(String name, int age) 9 { 10 setName(name); 11 setAge(age); 12 } 13 14 public void show() 15 { 16 System.out.println("Chinese - " + name + " " + age); 17 } 18 }
要寫無參數的構造函數;
要寫set方法和get方法;
要寫public的set和get方法;
固然也能夠寫一些其餘方法,由於對象建立出來是拿來用的不是拿來保存屬性值的。
c 在src目錄下面新建一個XML文件,例如appContext.xml。這個文件用於指導Spring容器構建什麼樣的對象。對於要用Spring容器構建對象的類,須要提供無參數的構造函數,不然報org.springframework.beans.BeanCreationException和org.springframework.beans.BeanInstantiationException等異常。
d appContext.xml的寫法:
1 要寫上xmlns,也就是XML namespace(命名空間),命名空間有惟一的URI。Java和XML都不會檢查該URI是否有效,可是Spring會檢查。所以要寫上正確的URL。若是xmlns的URI是什麼奇怪的東西而不是http://www.springframework.org/schema/beans,將報錯提示找不到<beans>.
2 也要寫上xmlns:xsi屬性,這個是XML的規範,一樣不能寫其餘奇怪的東西,必須寫真正的XML規範的URL。瀏覽器能夠訪問到這個URL。
3 xmlns:aop之類的,愛寫什麼寫什麼。。。(Spring只是選擇性強迫症,不檢查這個)
4 xsi:schemaLocation要寫正確的路徑(Spring至少會先檢查這裏面的URL個數是否是偶數個 = =)
5 剩下就是告訴spring如何new對象了。
<bean id="變量名" name="包.類"> //必定要加雙引號
<property name="屬性的變量名"> //要雙引號
<value>XXX<value> //要寫正確的屬性值,不然報類型錯誤異常。
</property>
</bean>
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!-- ApplicationContext Objects Configuration --> 3 <beans 4 xmlns="http://www.springframework.org/schema/beans" 5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 6 7 xmlns:aop="what the fuck...here...a =3=oooooops!" 8 xmlns:tx="so what the fuck...here..tx" 9 10 xsi:schemaLocation="http://www.springframework.org/schema/beans 11 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 12 http://www.springframework.org/schema/aop 13 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 14 http://www.springframework.org/schema/tx 15 http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" 16 > 17 18 <bean id="chinese" class="com.bean.Chinese"> 19 <property name="name"> 20 <value>"小明"</value> 21 </property> 22 <property name="age"> 23 <value>10</value> 24 </property> 25 </bean> 26 27 <bean id="french" class="com.bean.French"> 28 <property name="name"> 29 <value>"Von"</value> 30 </property> 31 <property name="age"> 32 <value>11</value> 33 </property> 34 </bean> 35 </beans> 36 37 <!-- 38 xmlns="http://www.springframework.org/schema/beans" 39 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 40 xmlns:aop="http://www.springframework.org/schema/aop" 41 xmlns:tx="http://www.springframework.org/schema/tx" 42 xsi:schemaLocation="http://www.springframework.org/schema/beans 43 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 44 http://www.springframework.org/schema/aop 45 http://www.springframework.org/schema/aop/spring-aop-2.0.xsd 46 http://www.springframework.org/schema/tx 47 http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" 48 > 49 -->
6 寫個main函數:
使用ApplicationContext類來建立對象。這個方法是阻塞的,會等Spring搞完了再繼續運行。實際上,用這一方式來建立對象相對與直接new,須要比較長的時間。ApplicationContext是個抽象類,他有三個子類,用來分別從不一樣的地方讀取XML文件:
ClassPathXmlApplicationContext在src目錄下找
FileSystemXmlApplicationContext從文件系統裏找
XmlWebApplicationContext去Web項目裏找
能夠經過get方法獲得構建好的對象的引用。這些代碼都是不須要try的,前提是用戶確保XML是正確的(不然代碼不是拋異常這麼簡單,而是徹底不能用)。
1 package com.bean; 2 3 import org.springframework.context.*; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 public class Main { 7 8 public static void main(String[] args) 9 { 10 Person p = null; 11 try{ 12 @SuppressWarnings("resource") 13 ApplicationContext context = new ClassPathXmlApplicationContext("appContext.xml"); 14 p = (Person) context.getBean("chinese"); 15 p.show(); 16 p = (French) context.getBean("french"); 17 p.show(); 18 } 19 catch(Exception ex) 20 { 21 ex.printStackTrace(); 22 } 23 } 24 }
第一個Spring Demo到此結束。
7 爲何這樣就解藕了?
在傳統的模式中,new什麼對象是代碼裏說了算的。若是將類的構建挪出來,並容許在外部的XML中定義如何構建他,就能夠經過修改外部的XML文件來更改程序的行爲,而不須要從新編譯。
在傳統的模式下,「神說,要有光」,而後神要去發明光,纔會有。下一次咱們想要黑色的光呢(固然沒有光是黑色的),須要在「創世紀」這個程序的代碼裏修改new語句,在初始化階段修改對象的屬性,或者把new Light()改稱new DarkLight(),但這最好保證兩個類是同一個父類的多態類或來自同一個接口,而且沒有不一致的其餘方法。
在Spring中,「神說要有光,因而就有了光」,光是根據XML的配置來注入給神的。下一次咱們想要黑色的光了呢,改一下XML裏光對象的屬性值,或者,把bean的class屬性由Light改爲DarkLight,從新運行「創世紀」程序,光就變黑了!
其餘連接: