Spring基本介紹 1.官方資料和下載 1.1Spring5下載 直接訪問 https://repo.spring.io/ui/native/release/org/springframework/spring/,選擇相應版本即可 進入官網 https://spring.io/ 進入Spring5 ...
Spring基本介紹
1.官方資料和下載
1.1Spring5下載
直接訪問 https://repo.spring.io/ui/native/release/org/springframework/spring/,選擇相應版本即可
-
進入官網 https://spring.io/
-
進入Spring5
-
進入Spring5 的github
-
在github倉庫README.md文件往下拉,看到Access to Binaries,點擊裡面的鏈接
-
在新頁面往下拉,看到如下標題,點擊鏈接
-
點擊Artifacts
-
在左邊的彈窗中依次點擊release-->org-->springframework-->spring
-
在右邊的視窗點擊複製url
-
在瀏覽器新頁面訪問該地址,在頁面中即可選擇你想要下載的版本,我這裡選擇下載5.3.8版本
-
點擊對應版本,在新頁面中選擇第一個,點擊即可下載
1.2Spring文檔
-
線上文檔
-
離線文檔
解壓縮後,在\spring-framework-5.3.8\docs\reference目錄下分別提供了spring介紹文檔的html和pdf版本
-
離線API
在\spring-framework-5.3.8\docs\javadoc-api\index.html中可以查看Spring的API
2.Spring學習的核心內容
- Spring核心學習內容:IOC,AOP,JDBCTemplate
- IOC:控制反轉,可以管理java對象
- AOP:切麵編程
- JDBCTemplate:是Spring提供的一套訪問資料庫的技術,應用性強,相對好理解
- 聲明式事務:基於ioc/aop實現事務管理
- 其中ioc,aop是重點以及難點
3.Spring幾個重要概念
- Spring可以整合其他的框架(Spring是管理框架的框架)
- Spring有兩個核心的概念:IOC 和 AOP
- IOC [Inversion Of Control 反轉控制]:
-
傳統的開發模式 [ JdbcUtils/反射 ]
程式------->環境 //程式讀取環境配置,然後自己創建對象
傳統的開發模式:(以連接到資料庫為例說明)
-
程式員編寫程式,在程式中讀取資料庫配置信息
-
創建對象(反射或者new)
各種對象,如:Connection,PreparedStatement,ResultSet等等
-
使用對象完成任務
-
-
IOC的開發模式
程式<------容器 //容器創建好對象,程式直接使用
如,現在有幾個類:EmpAction EmpService EmpDao Emp
傳統的方式是通過手動new創建對象,然後在程式中使用
現在,可以把要使用到的對象先配置到一個文件中(xml或者註解,這裡以xml配置為例),這個文件可以理解成一個“容器文件”。配置好後,當spring啟動以後,它就可以直接在程式中來獲取容器創建好的對象,併進行使用:
-
Spring根據配置文件xml/註解,創建對象,並放入到容器中(類似ConcurrentHashMap),並且可以完成對象之間的依賴(對象之間的依賴關係也在xml配置或者註解中完成)
依賴:即對象間的引用關係。例如有A,B兩個類。A類中的某個屬性是B類,通過容器創建的兩個類的對象a,b,它們之間的依賴/引用關係,將會自動完成(當然,也需要配置)
-
當需要使用某個對象實例時,直接從容器中獲取即可
-
這樣程式員可以更加專註於使用對象完成相應的業務
這樣創建對象的方式就從 new ===> 註解/配置方式
-
-
DI(Dependency Injection 依賴註入),可以理解成是IOC的另外叫法
-
Spring最大的價值:通過配置,給程式員提供需要使用的 web層[Servlet(Action/Controller)]/Service/Dao/JavaBean等對象。這是Spring的核心價值所在,也是ioc的具體體現,實現解耦
-
原先的開發模式,Servlet是tomcat創建的,然後Servlet中如果你要用什麼對象實例(如Service),就new一個,在Service中你要使用什麼實例(如Dao),也同樣是通過new的方式來創建實例……以此類推
-
當使用Spring以後,web層的Servlet,Service層,Dao層,Javabean[entity]中的所有對象,我們都可以在配置文件中配置(或者通過註解指定),並且指定好對象間的依賴關係,放入到容器中。當這個流程結束後,我們想在程式中使用哪個對象,都可以直接在容器中直接獲取。
-
4.Spring快速入門
4.1需求說明
通過Spring的方式[配置文件],獲取JavaBean:Monster的對象,並給該對象的屬性賦值,輸出該對象信息
4.2完成步驟
-
下載spring 5 開發包
詳見1.1.1spring5下載
-
創建Java工程
為了清晰spring5 的各個jar包的作用,這裡使用Java工程
-
新建一個lib文件夾,引入開發spring5的基本包
commons-logging.jar包需要另外下載,不在spring5包中
4.3代碼實現
-
創建Javabean:Monster.java
package com.li.bean; /** * @author 李 * @version 1.0] * Javabean / Entity */ public class Monster { private Integer monsterId; private String name; private String skill; //無參構造器一定要有,spring底層反射創建對象時需要使用 public Monster() { } public Monster(Integer monsterId, String name, String skill) { this.monsterId = monsterId; this.name = name; this.skill = skill; } public Integer getMonsterId() { return monsterId; } public void setMonsterId(Integer monsterId) { this.monsterId = monsterId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSkill() { return skill; } public void setSkill(String skill) { this.skill = skill; } @Override public String toString() { return "Monster{" + "monsterId=" + monsterId + ", name='" + name + '\'' + ", skill='" + skill + '\'' + '}'; } }
-
在src目錄下創建配置文件:滑鼠右擊src目錄--->new--->XML Configuration File--->Spring Config,我這裡起名為beans.xml
-
創建好配置文件後,文件上方顯示"Applilcation context not configured for this file",點擊右邊的Create Spring facet
在彈出的視窗中直接點擊右下方的ok
然後重新點擊文件的Create Spring facet
在新視窗選中beans.xml文件,然後點擊ok,之後文件就不再提示了。
-
在beans.xml文件中配置monster對象
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 1. 配置monster對象/javabean 2. 在 beans標簽中可以配置多個bean 3. 一個bean就是一個Javabean對象 4. class屬性用於指定類的全路徑->spring底層反射要用 5. id屬性表示該java對象在spring容器中的id(將來在程式中通過id在容器中獲取相應對象,因此id是唯一的) 6. <property name="monsterId" value="100"/> 用於給該對象的屬性賦值,沒有的話就是預設值 --> <bean class="com.li.bean.Monster" id="monster01"> <property name="monsterId" value="100"/> <property name="name" value="牛魔王"/> <property name="skill" value="芭蕉扇"/> </bean> </beans>
-
創建測試類SpringBeanTest
package com.li.test; import com.li.bean.Monster; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.testng.annotations.Test; /** * @author 李 * @version 1.0 */ public class SpringBeanTest { @Test public void getMonster() { // 1.創建容器 ApplicationContext // 2.這個容器是和配置文件關聯的。也就是說,將來可能會有多個容器,因為配置文件可能會有多個 ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml"); // 3.通過getBean獲取對應的對象 // 預設返回的是Object類型(編譯類型),但是運行類型是Monster // Object monster01 = ioc.getBean("monster01"); Monster monster01 = (Monster) ioc.getBean("monster01");//這樣就可以在編譯時獲取對象屬性 //4.輸出 System.out.println("monster01=" + monster01 + " 運行類型=" + monster01.getClass()); System.out.println("monster01.id=" + monster01.getMonsterId() + " monster01.name=" + monster01.getName() + " monster01.skill=" + monster01.getSkill()); //5.相比於強轉,也可以直接在獲取的時候指定Class類型 Monster monster011 = ioc.getBean("monster01", Monster.class); System.out.println("monster011=" + monster011); System.out.println("monster011.name=" + monster011.getName()); System.out.println("ok~~~"); } }
4.4註意事項和細節
4.4.1類載入路徑
一個問題:為什麼下麵可以讀取到beans.xml文件?或者說,讀取的文件是src目錄下的beans.xml嗎?
ApplicationContext ioc =new ClassPathXmlApplicationContext("beans.xml");
我們可以在測試類中輸出一下路徑:
//驗證類載入路徑
@Test
public void classPath() {
File file = new File(this.getClass().getResource("/").getPath());
System.out.println("file=" + file);
}
可以看到類的載入路徑並不在src目錄,而是在一個out目錄下:
可以看到在out\production\spring目錄下有一個beans.xml文件:
當運行後,會將src目錄下編譯好的class文件放到out目錄下。同時,將資源文件(這裡指beans.xml)也放到out目錄,讀取的時候是按照out目錄來讀取的。
因此運行時,真正讀取的配置文件不是在src目錄下的beans.xml,而是在out目錄下的beans.xml,只是兩個文件是一樣的。(類的載入路徑)
回到之前的問題,為什麼下麵的語句,我們直接寫“beans.xml”?
ApplicationContext ioc =new ClassPathXmlApplicationContext("beans.xml");
因為預設讀取的是.....\out\production\spring目錄,而一旦運行過後,在src目錄下的beans.xml文件會被直接放在.....\out\production\spring目錄下,因此可以直接讀取到。
假如beans.xml文件是放到src下麵的某個子文件夾,那麼在語句中就要根據子文件夾的結構來進行修改。
4.4.2spring容器的結構/機制
註意配置debugger,通過配置指定哪一些數據在debug的時候會展示,哪一些不展示
1.如下,打上斷點,點擊debug
2.如下,beanFactory的beanDefinitionMap屬性的類型是ConcurrentHashMap集合,保存beans.xml中的bean節點配置的bean對象的信息
因為在我們的配置文件中,通常會有很多的java對象信息,spring會把這些java對象的信息保存下來,以便將來spring創建對象時使用
3.展開beanDefinitionMap對象,可以看到一個table數組(ConcurrentHashMap類型),初始的大小為512。Spring會將java對象的信息放到table中。
4.index=127位置以ConcurrentHashMap$Node類型保存Monster01對象信息
其中key=“monster01”就是beans.xml中配置的bean的id
value存放了很多數據,例如:monster01對象的信息(屬性,屬性值,類信息,是否懶載入)
propertyValues就是記錄beans.xml中配置的monster01對象的屬性名和屬性值
5.此外beanFactory還有一個重要屬性singletonObjects,singletonObjects也是一個ConcurrentHashMap集合
....未完