一:spring的基本特徵java
Spring是一個很是活躍的開源框架;它是一個基於Core來架構多層JavaEE系統的框架,它的主要目的是簡化企業開發。Spring以一種非侵入式的方式來管理你的代碼,Spring提倡「最少侵入,這也意味着你能夠適當的時候安裝或卸載Spring。node
二:開發Spring所須要的工具程序員
1.Spring的jar包spring
到http://www.springsource.org/download下載spring,而後進行解壓縮,在解壓目錄中找到下面jar文件,拷貝到類路徑下 編程
若是使用了切面編程(AOP),還須要下列jar文件 lib/aspectj/aspectjweaver.jar和aspectjrt.jar lib/cglib/cglib-nodep-2.1_3.jar tomcat
若是使用了JSR-250中的註解,如@Resource/@PostConstruct/@PreDestroy,還須要下列jar文件 lib\j2ee\common-annotations.jar 注:JSR(Java 規範請求)是指向JCP(Java Community Process)提出新增一個標準化技術規範的正式請求。任何人均可以提交JSR(Java 規範請求),以向Java平臺增添新的API和服務。JSR已成爲Java界的一個重要標準。session
2.Spring的配置文件架構
默認狀況下是applicationContext.xml文件。能夠建不少XML文件,工程中通常都是這樣配置的。mvc
三:Spring基本功能及案例詳解app
1.Spring的IOC
SpringIOC(控制反轉):把對象的建立,初始化,銷燬等工做交給Spring容器來作。由Spring容器控制對象的生命週期。
步驟:A:啓動Spring容器;B:從Spring容器中把對象取出來;C:最後,對象調用實際的業務方法。
A:啓動Spring容器:
在類路徑下尋找配置文件來實例化容器:ApplicationContext context = new ClassPathXmlApplicationContext("配置文件類路徑");
經過這種方式加載。須要將spring配置文件放到當前項目的classpath路徑下。classpath路徑指的是當前項目的src目錄,該目錄是java源文件的存放位置。
在文件系統路徑下尋找配置文件來實例化容器:ApplicationContext context = new FileSystemXmlApplicationContext("配置文件系統路徑");
注:常常採用第一種方式啓動Spring容器。
B:從Spring容器中把對象取出來:
context.getBean("配置文件中bean的id"); 如:HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");
C:對象調用實際的業務方法:
helloWorld.hello();
1.1.Spring容器建立對象的方式
A:默認的狀況下是調用該類默認的無參構造函數來建立類的對象。
案例:
Spring的主配置文件:applicationContext.xml(由於我這裏將會講到不少模塊,因此我用一個主配置文件去加載各個模塊的配置文件):
具體業務模塊配置文件applicationContext-creatobject.xml
業務類HelloWorld.java
客戶端代碼:
由此看出:若是業務類HElloWorld.java又寫了該類的有參構造函數,此時就覆蓋了默認的無參構造函數。這樣就致使Spring容器在建立該類的對象時失敗。由於默認的是調用該類的默認無參構造函數,而此時又找不到無參構造函數了,因此就建立對象失敗。
B:Spring容器利用靜態工廠方法建立類對象。
案例:
Spring的主配置文件:applicationContext.xml(由於我這裏將會講到不少模塊,因此我用一個主配置文件去加載各個模塊的配置文件):
具體業務模塊配置文件applicationContext-creatobject-method.xml
業務類HelloWorld.java
靜態工廠類方法:
客戶端代碼:
C:Spring容器利用實例工廠方法建立對象
再次不作案例分析,記住便可。
最後說明一下:spring配置文件中,只要是一個bean就會爲該bean建立對象(默認是調用該類的默認構造函數建立對象)
1.2.Spring配置文件中別名的用法
案例:
Spring的主配置文件:applicationContext.xml(由於我這裏將會講到不少模塊,因此我用一個主配置文件去加載各個模塊的配置文件):
具體業務模塊配置文件applicationContext-alias.xml
業務類HelloWorld.java
客戶端代碼:
由此看出:經過配置文件中的配置,能夠達到在一個地方命名,在多個地方使用不一樣的名字的效果。
1.3.Spring容器建立對象的時機
案例:
Spring的主配置文件:applicationContext.xml(由於我這裏將會講到不少模塊,因此我用一個主配置文件去加載各個模塊的配置文件):
具體業務模塊配置文件applicationContext-creatobject-when.xml
業務類HelloWorld.java
客戶端代碼:
執行結果:
由執行結果可看出:在單例狀況下(默認就是單例,關於單例,下面會講到):
A:在默認狀況下,啓動spring容器的時候(ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml)),就調用該類的無參構造函數建立對象。因此spring容器建立對象的時機是:啓動spring容器時建立。
B:在spring的配置文件bean中有一個屬性lazy-init="default/false/true":
a:若是lazy-init="default/false",在啓動spring容器的時候建立對象。
b:若是lazy-init="true",在獲取對象的時候建立對象,即context.getBean()時,建立對象。
a與b的意義:
在第一種狀況下能夠在啓動spring容器的時候,檢查spring配置文件的正確性。若是再結合tomcat,若是spring容器不能正常啓動整個tomcat就不能正常啓動。可是這樣的缺點是把一些bean過早的放在了內存中,若是有數據,則對內存來講是一個消耗。在第二種狀況下,能夠減小內存的消耗,可是不容易檢查出配置文件中的錯誤,排錯比較困難。
1.4.Spring容器中bean的單例與多例
案例:
Spring的主配置文件:applicationContext.xml(由於我這裏將會講到不少模塊,因此我用一個主配置文件去加載各個模塊的配置文件):
具體業務模塊配置文件applicationContext-creatobject-scope.xml
業務類HelloWorld.java
客戶端代碼:
執行結果:
在配置文件的bean中的scope="singleton"的狀況下(即默認狀況下):
在配置文件的bean中的scope="prototype"的狀況下:
從執行的結果,咱們來總結概括一下:
從第一個執行結果看出,由spring容器產生的bean默認是單例的。打印結果看出,兩次分別獲取的bean結果是同樣的。而且單例模式下,spring容器在啓動的時候建立對象。
從第二個執行結果看出,若果將配置文件中的bean的scope值修改成「prototype」,那麼由spring容器產生的bean就是多例的。打印結果看出,兩次分別獲取的bean結果是不同的。而且在多例模式下,spring容器在context.getBean(),即獲取對象的時候建立對象。這裏有兩次獲取bean,因此打印出兩個:new instance-----scope
綜上:能夠在spring的配置文件 ,scope的值進行修改="singleton/prototype/request/session/global session/global" ,若是spring的配置文件的scope爲「prototype」,則在獲得或者說從spring容器獲取該bean的時候才建立對象。
1.5.Spring容器中對象的生命週期
案例
Spring的主配置文件:applicationContext.xml(由於我這裏將會講到不少模塊,因此我用一個主配置文件去加載各個模塊的配置文件):
具體業務模塊配置文件applicationContext-initdestory.xml
業務類HelloWorld.java
客戶端代碼:
執行結果:
由執行結果的順序能夠看出:在單例狀況下,即默認scope="singleton"的時候
a:spring容器在啓動的時候建立對象;
b:spring容器執行init方法;
c:程序員調用本身的業務方法;
d:當spring容器關閉的時候執行destory方法。
spring容器:ApplicationContext applicationContext = new ClassPathXmlApplicationContext("");
它的關閉:須要將applicationContext轉化一下:
ClassPathXmlApplication cpxa = (ClassPathXmlApplicationContext) applicationContext;
cpxa.close(); 這樣才能關閉spring容器,執行destory方法。
注意:當scope=「prototype」的時候(即多例的狀況下),spring容器不會執行destory()方法。
2.Spring的DI(依賴注入)
springDI:理解爲依賴注入,俗稱給屬性賦值。
日常中,咱們給類的屬性賦值,無非兩種方式:1.調用類的set,get方法;2.調用類的構造方法。好比下面一個類中的屬性類型,幾乎表明了全部類型:
public class Person{
private Long pid;
private String pname;
private Student student;
private List lists;
private Set sets;
private Map map;
private Properties properties;
//set,get方法
}
說明:一個類中的全部屬性均可以採用SpringDI的方式賦值,但並非全部的屬性都適合賦值。
2.1.調用類的set,get方法
案例:
Spring的主配置文件:applicationContext.xml(由於我這裏將會講到不少模塊,因此我用一個主配置文件去加載各個模塊的配置文件):
具體業務模塊配置文件applicationContext-di-set.xml
業務類Person.java
業務類Student.java
客戶端代碼:
執行結果:
總結:從業務中的標註看,
1.我這裏使用了本身編寫的工具類SpringInit.java,是爲了方便2的使用;
工具類的代碼以下:
public class SpringInit{
public static ApplicationContext context;//spring容器
//靜態代碼塊,在類加載的以後執行,只執行一次
static{
context = new ClassPathXmlApplicationContext("applicationContext.xml");//啓動spring容器
}
}
而後個人客戶端類繼承了這個工具類。
結合配置文件和執行結果,看出是經過set方法賦值的。首先建立對象解析全部的property,把name解析出來,拼接成set方法,把value和ref解析出來並賦值。
2.2.調用類的構造方法
案例:
Spring的主配置文件:applicationContext.xml(由於我這裏將會講到不少模塊,因此我用一個主配置文件去加載各個模塊的配置文件):
具體業務模塊配置文件applicationContext-di-constructor.xml
業務類同1.1中的業務類相同,只是Person類中添加一個構造方法:
public Person(String pname,Student){
this.pname = pname;
this.student = student;
}
客戶端代碼:
執行結果:
總結:構造函數的方式賦值:
2.3.spring的IOC與DI的意義
案例:
Spring的主配置文件:applicationContext.xml(由於我這裏將會講到不少模塊,因此我用一個主配置文件去加載各個模塊的配置文件):
具體業務模塊配置文件applicationContext-document.xml
業務類:
ducument接口:
三個實現接口的類:
------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
文檔管理類DocumentManager.java
客戶端代碼:
執行結果:
從例子能夠看出,Spring的IOC與DI的完美結合,是其作到了真正的面向接口編程。若是咱們想讀寫Excel或者Word,只須要修改配置文件中的傳入參數便可。而傳統的方式是不徹底面向接口的編程,把實現類暴露給客戶端了。
2.3.spring的IOC與DI實現mvc的模擬例子
案例:
Spring的主配置文件:applicationContext.xml(由於我這裏將會講到不少模塊,因此我用一個主配置文件去加載各個模塊的配置文件):
具體業務模塊配置文件applicationContext-mvc.xml
業務類:
服務層接口與實現:
-----------------------------------------------------------------------------------------------
dao層接口與實現:
------------------------------------------------------------------------------------------
控制層action
客戶端代碼:
執行結果:
從例子能夠看出,Spring的IOC與DI的完美結合,是其作到了真正的面向接口編程。這裏的依賴注入都採用了set的方式注入的。