1. IoC 控制反轉
對控制反轉的理解:
控制反轉是一種思想。
控制反轉是為了降低程式耦合度,提高程式擴充套件力,達到OCP原則,達到DIP原則。
控制反轉,反轉的是什麼?
- 將物件的建立權利交出去,交給第三方容器負責。(我的理解:也就是不用自己new 物件了 , 交給Spring容器進行處理)
- 將物件和物件之間關係的維護權交出去,交給第三方容器負責。
控制反轉這種思想如何實現呢?
- DI(Dependency Injection):依賴注入 (控制反轉的具體實現)
2. 依賴注入
對依賴注入的理解
依賴注入實現了控制反轉的思想。
Spring透過依賴注入的方式來完成Bean管理的。
Bean管理說的是:Bean物件的建立,以及Bean物件中屬性的賦值(或者叫做Bean物件之間關係的維護)。
依賴注入:
- 依賴指的是物件和物件之間的關聯關係。
- 注入指的是一種資料傳遞行為,透過注入行為來讓物件和物件產生關係。
依賴注入常見的實現方式包括兩種:
- 第一種:set注入
- 第二種:構造注入
2.1 set 注入
set注入,基於set方法實現的,底層會透過反射機制呼叫屬性對應的set方法然後給屬性賦值。這種方式要求屬性必須對外提供set方法。
重點內容:
<?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">
<bean id="userDaoBean" class="com.north.spring6.dao.UserDao"/>
<bean id="userServiceBean" class="com.north.spring6.service.UserService">
<property name="userDao" ref="userDaoBean"/>
</bean>
</beans>
實現原理
透過property標籤獲取到屬性名:userDao
透過屬性名推斷出set方法名:setUserDao
透過反射機制呼叫setUserDao()方法給屬性賦值
property標籤的name是屬性名。
property標籤的ref是要注入的bean物件的id。(透過ref屬性來完成bean的裝配,這是bean最簡單的一種裝配方式。裝配指的是:建立系統元件之間關聯的動作)
透過測試看到程式仍然可以正常執行,說明property標籤的name是:setUserDao()方法名演變得到的。演變的規律是:
- setUsername() 演變為 username
- setPassword() 演變為 password
- setUserDao() 演變為 userDao
- setUserService() 演變為 userService
另外,對於property標籤來說,ref屬性也可以採用標籤的方式,但使用ref屬性是多數的:
<bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
<property name="userDao">
<ref bean="userDaoBean"/>
</property>
</bean>
總結:set注入的核心實現原理:透過反射機制呼叫set方法來給屬性賦值,讓兩個物件之間產生關係。
2.2 構造注入
核心原理:透過呼叫構造方法來給屬性賦值。
xml 檔案配置資訊:
<?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">
<bean id="userDaoBean" class="com.north.spring6.dao.UserDao"></bean>
<bean id="userServiceBean" class="com.north.spring6.service.UserService">
<!--第一種配置方式-->
<!--<constructor-arg ref="userDaoBean"></constructor-arg>-->
<!--第二種配置方式-->
<!--<constructor-arg index="0" ref="userDaoBean"></constructor-arg>-->
<!--第三種配置方式-->
<constructor-arg name="userDao" ref="userDaoBean"></constructor-arg>
</bean>
</beans>
透過測試得知,透過構造方法注入的時候:
- 可以透過下標
- 可以透過引數名
- 也可以不指定下標和引數名,可以型別自動推斷
Spring在裝配方面做的還是比較健壯的。
3. set 注入專題
3.1 注入外部 bean
外部Bean的特點:bean定義到外面,在property標籤中使用ref屬性進行注入。通常這種方式是常用。
<?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">
<bean id="userDaoBean" class="com.north.spring6.dao.UserDao"/>
<bean id="userServiceBean" class="com.north.spring6.service.UserService">
<property name="userDao" ref="userDaoBean"/>
</bean>
</beans>
3.2 注入內部 bean
內部Bean的方式:在bean標籤中巢狀bean標籤。
<?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">
<bean id="userServiceBean" class="com.north.spring6.service.UserService">
<property name="userDao">
<bean class="com.north.spring6.dao.UserDao"/>
</property>
</bean>
</beans>
3.3 注入簡單型別
需要特別注意:如果給簡單型別賦值,使用value屬性或value標籤。而不是ref。
透過原始碼分析得知,簡單型別包括:
- 基本資料型別
- 基本資料型別對應的包裝類
- String或其他的CharSequence子類
- Number子類
- Date子類
- Enum子類
- URI
- URL
- Temporal子類
- Locale
- Class
- 另外還包括以上簡單值型別對應的陣列型別。
3.4 級聯屬性賦值 (瞭解)
<?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">
<bean id="clazzBean" class="com.north.spring6.beans.Clazz"/>
<bean id="student" class="com.north.spring6.beans.Student">
<property name="name" value="張三"/>
<!--要點1:以下兩行配置的順序不能顛倒-->
<property name="clazz" ref="clazzBean"/>
<!--要點2:clazz屬性必須有getter方法-->
<property name="clazz.name" value="高三一班"/>
</bean>
</beans>
要點:
- 在spring配置檔案中,如上,注意順序。
- 在spring配置檔案中,clazz屬性必須提供getter方法。
3.5 注入陣列
3.6 注入List集合
3.7 注入Set集合
3.8 注入Map集合
3.9 注入Properties
3.10 注入null和空字串
3.11 注入的值中含有特殊符號
4. 基於p名稱空間的注入
P名稱空間注入:底層實際上還是
set
注入 , 用於簡化set
注入 , 注意:不能省略set方法
5. 基於c名稱空間的注入
基於
構造放啊
, 簡化構造注入
, 注意:不能省略構造方法
6. util 名稱空間讓配置複用
7. 基於XML的自動裝配
7.1 根據名稱自動裝配
7.2 根據型別自動裝配
8. Spring 引入外部屬性配置檔案