Spring IOC概述—依賴注入,集合注入,SPEL,自動裝配

一.Spring IOC是什麼

1.IOC簡述
 Ioc—Inversion of Control,即“控制反轉”,是一種設計思想。在Java開發中,Ioc意味着將你設計好的對象交給容器控制,而不是傳統的在你的對象內部直接控制。簡言之,就是使用對象的時候不再“隨用隨new”,也不用new一個對象然後給它賦值,這些通過IOC容器都能由系統自動生成。

2.Spring IOC優點

  1. 輕量級 2. 依賴注入 3. 面向切面編程 4. 容器 5. 一站式

二.如何使用Spring IOC

  1. 搭建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 的名稱作爲鍵值
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章