【Java】 Spring依賴注入小試牛刀:編寫第一個Spring ApplicationContext Demo

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,從新運行「創世紀」程序,光就變黑了!

 

 

其餘連接:

依賴注入與JSR-300的參考實現-Guice

百度百科:Guice和Spring的對比

相關文章
相關標籤/搜索