一.Spring IOC是什麼
1.IOC簡述
Ioc—Inversion of Control,即“控制反轉”,是一種設計思想。在Java開發中,Ioc意味着將你設計好的對象交給容器控制,而不是傳統的在你的對象內部直接控制。簡言之,就是使用對象的時候不再“隨用隨new”,也不用new一個對象然後給它賦值,這些通過IOC容器都能由系統自動生成。
2.Spring IOC優點
- 輕量級 2. 依賴注入 3. 面向切面編程 4. 容器 5. 一站式
二.如何使用Spring IOC
- 搭建Spring 環境
1.引入4個所需jar包 spring-beans spring-context spring-core spring expression
2.配置文件,在target\classes\config目錄下創建applicationContext.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
2.作用域scope
1.singleton (默認屬性)
Spring將Bean放入Spring IOC容器的緩存池中,並將Bean引用返回給調用者,spring
IOC繼續對這些Bean進行後續的生命管理。BeanFactory只管理一個共享的實例。所有對這個特定 bean的實例請求,都導致返回這個唯一
bean實例的引用。
即每次拿到的對象都是引用的同一個地址的對象。當一個bean被標識爲singleton時候,spring的IOC容器中只會存在一個該bean。
2.prototype
Spring將Bean返回給調用者,調用者負責Bean後續生命的管理,Spring不再管理這些Bean的生命週期。
每次對這個bean的實例請求都會導致一個新的實例的創建。當用戶需要不受其他用戶對象影響的對象或有類似的需求時,這是一個較理想的解決辦法。
即每次拿到的對象都是引用的不同地址的對象。相當於一個new的操作。清除prototype作用域的對象並釋放任何prototype bean所持有的昂貴資源,都是客戶端代碼的職責
3.依賴注入
3.1.屬性注入步驟
3.1.1.在目標類中聲明屬性並生成Set方法
3.1.2.在xml文件中進行配置
<bean id="apple" class="com.zzxtit.spring.ioc.dev.Apple" scope="prototype" name="weight" value="0.5KG"></bean>
<bean id="banana" class="com.zzxtit.spring.ioc.dev.Banana" name="weight" value="0.2KG"></bean>
3.1.3在Test類中使用
注:若屬性值爲引用類型,則value換成ref,引號的內容換爲該引用類型在bean中注入時的id
public static void main(String[] args) {
Apple apple = (Apple) FruitFactory.getFruit("apple");
Orange orange = (Orange) FruitFactory.getFruit("orange");
System.out.println(orange + "============>" + apple);
}
3.2.構造器注入(通過構造方法注入)
spring 通過構造器注入,兩種方式:
3.2.1、通過構造方法的參數的順序,使用屬性INDEX, 從0開始。使用方法同3.1.3
<bean id="constructorDi" class="com.zzxtit.spring.ioc.di.ConstructorDI">
<constructor-arg index="0" ref="apple">
</constructor-arg>
<constructor-arg index="1" value="張三">
</constructor-arg>
<constructor-arg index="2" value="19">
</constructor-arg>
</bean>
3.2.2、通過參數的類型確認使用的構造方法,使用屬性ype, 如果基本數數據類型或者String類型,直接寫類型名稱,如果是自定義或者其他引用類型,需要全類名。使用方法同3.1.3。
<bean id="constructorDi" class="com.zzxtit.spring.ioc.di.ConstructorDI">
<constructor-arg type="java.lang.String" alue="realName李學霸">
</constructor-arg>
<constructor-arg type="java.lang.String" value="userName李學霸">
</constructor-arg>
<constructor-arg type="com.zzxtit.spring.ioc.di.Apple" ref="apple">
</constructor-arg>
<constructor-arg type="int" value="19">
</constructor-arg>
</bean>
4.注入集合(List Map Set properties)
4.1.在xml中將所需集合注入
<bean id="collectionDi"
class="com.zzxtit.spring.ioc.di.CollectionDI">
<property name="stuList">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
<property name="major">
<set>
<value>major1</value>
<value>major2</value>
<value>major3</value>
</set>
</property>
<property name="score" ref="scoreMap">
<map>
<entry key="stu1" value="70"></entry>
<entry key="stu2" value="79"></entry>
<entry key="stu3" value="76"></entry>
</map>
</property>
<property name="pro">
<props>
<prop key="mysql_url">jdbc:mysql://localhost:3306/test</prop>
<prop key="mysql_driver">com.jdbc.mysql.Driver</prop>
<props>
</property>
</bean>
4.2.在Test類中調用IOC容器創建CollectionDi對象
注:CollectionDi類重寫toString方法便於結果顯示,代碼如下
@Override
public String toString() {
return "CollectionDI [stuList=" + stuList.getClass() + ", majorList=" + majorList.getClass() + ", score=" + score.getClass() + ", pro=" + pro
+ "]";
}
測試類中代碼如下
public static void main(String[] args) {
ApplicationContext ioc = new ClassPathXmlApplicationContext("config/applicationContext-di.xml");
//參數爲applicationContext-di.xml目錄
CollectionDI collectionDi = ioc.getBean("collectionDi", CollectionDI.class);
System.out.println("============>" + collectionDi);
//因爲重寫了toString,所以打印結果是集合的內容
}
5 util標籤,p命名空間,引入外部屬性文件
5.1使用 util schema 裏的集合標籤定義獨立的集合 Bean,可以被公用。
注:使用util標籤時需引入:
1、命名空間:xmlns:util=“http://www.springframework.org/schema/util”
2、引入xsd文件:http://www.springframework.org/schema/util
https://www.springframework.org/schema/util/spring-util.xsd
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/util
https://www.springframework.org/schema/util/spring-util.xsd">
</beans>
聲明如下
<util:map id="scoreMap">
<entry key="張" value="70"></entry>
<entry key="李" value="79"></entry>
<entry key="趙" value="76"></entry>
</util:map>
使用如下,在properties中用ref引用被聲明的bean的id
<bean id="collectionDi"
class="com.zzxtit.spring.ioc.di.CollectionDI">
<property name="score" ref="scoreMap">
</property>
</bean>
5.2 p命名空間
Spring 從 2.5 版本開始引入了一個新的 p 命名空間,可以通過 <bean> 元素屬性的方式配置 Bean 的屬性
注:使用p命名空間需要引入命名空間:xmlns:p="http://www.springframework.org/schema/p"
xmlns:p="http://www.springframework.org/schema/p"
p標籤的使用示例
<bean id="apple" class="com.springioc.Apple" p:color="紅色" p:type="普通">
</bean>
<bean id="studentPtest" class="com.springioc.Student" p:teacher-ref="teacher">
</bean>
5.3引入外部屬性文件
Spring 提供了一個 PropertyPlaceholderConfigurer 的 BeanFactory 後置處理器, 這個處理器允許用戶將 Bean 配置的部分內容外移到屬性文件中. 可以在 Bean 配置文件裏使用形式爲 ${var} 的變量, PropertyPlaceholderConfigurer 從屬性文件里加載屬性, 並使用這些屬性來替換變量.
Spring還允許在屬性文件中使用${propName},以實現屬性之間的相互引用。在Spring2.5之後:可通過<context:property-placeholder>元素,在<beans>中添加context Schema定義。在配置文件中添加如下配置:<context:property-placeholder location="calsspath:db.properties">
1).創建屬性文件:*.properties 文件內容爲key=value的鍵值方式
eg:在config文件夾下新建一個db.properties文件,內容如下
mysql_url=jdbc:mysql://localhost:3306/test
mysql_driver=com.jdbc.mysql.Driver
2).在xml文件中用${ }引用該文件內容
<!-- 引入properties 配置文件 -->
<context:property-placeholder location="config/db.properties"/>
<bean id="collectionDi" class="com.springioc.CollectionDI">
<property name="pro">
<props>
<prop key="mysql_url">${mysql_url}</prop>
<prop key="mysql_driver">${mysql_driver}</prop>
</props>
</property>
</bean>
6.SPEL
1.SPEL簡述
1.1.Spring 表達式語言(簡稱SpEL):是一個支持運行時查詢和操作對象圖的強大的表達式語言。
語法類似於 EL:SpEL 使用 #{…} 作爲定界符,所有在大框號中的字符都將被認爲是 SpEL
1.2.SpEL 爲 bean 的屬性進行動態賦值提供了便利
1.3.SpEL作用:
1).通過 bean 的 id 對 bean 進行引用
2).調用方法以及引用對象中的屬性
3).計算表達式的值
4).正則表達式的匹配
2.引用 Bean、屬性和方法
<bean id="stu" class="com.springioc.Student">
<property name="ci1" value="#{ci}">/property>
<property name="ci2" value="#{ci.toString}">/property>
<property name="ci3" value="#{ci.class}">/property>
</bean>
注:當value的值是一個方法時,其對應的property標籤的name值"ci2"應該爲一個屬性跟被引用方法( toString() )返回值相同的bean注入的類(Student)中的變量。
7.自動裝配
1).語法
<bean id="..." class=".." autowire="byType"/>
2).autowire屬性取值如下:
byType:按類型裝配,可以根據屬性的類型,在容器中尋找跟該類型匹配的bean。如果發現多個,那麼將會拋出異常。如果沒有找到,即屬性值爲null。
byName:按名稱裝配,可以根據屬性的名稱,在容器中尋找跟該屬性名相同的bean,如果沒有找到,即屬性值爲null。
Constructor:與byType的方式類似,不同之處在於它應用於構造器參數。如果在容器中沒有找到與構造器參數類型一致的bean,那麼將會拋出異常。
8.在classpath自動掃描Bean組件(通過加註解的方式)
1.特定組件包括:
@Component: 基本註解, 標識了一個受 Spring 管理的組件
@Repository: 標識持久層組件
@Service: 標識服務層(業務層)組件
@Controller: 標識表現層組件
注:對於掃描到的組件, Spring 有默認的命名策略: 使用非限定類名, 第一個字母小寫. 也可以在註解中通過 value 屬性值標識組件的名稱
2.@Autowired 註解自動裝配具有兼容類型的單個 Bean屬性
2.1.構造器, 普通字段(即使是非 public), 一切具有參數的方法都可以應用@Autowired 註解
2.2默認情況下, 所有使用 @Autowired 註解的屬性都需要被設置. 當 Spring 找不到匹配的 Bean 裝配屬性時, 會拋出異常, 若某一屬性允許不被設置, 可以設置 @Autowired 註解的 required 屬性爲 false
2.3默認情況下, 當 IOC 容器裏存在多個類型兼容的 Bean 時, 通過類型的自動裝配將無法工作. 此時可以在 @Qualifier 註解裏提供 Bean 的名稱. Spring 允許對方法的入參標註 @Qualifiter 以指定注入 Bean 的名稱
2.4@Autowired 註解也可以應用在數組類型的屬性上, 此時 Spring 將會把所有匹配的 Bean 進行自動裝配.
2.5@Autowired 註解也可以應用在集合屬性上, 此時 Spring 讀取該集合的類型信息, 然後自動裝配所有與之兼容的 Bean.
2.6@Autowired 註解用在 java.util.Map 上時, 若該 Map 的鍵值爲 String, 那麼 Spring 將自動裝配與之 Map 值類型兼容的 Bean, 此時 Bean 的名稱作爲鍵值