一、IoC配置
IoC的配置是通過Spring的xml文件的bean標簽進行的。
1、bean標簽介紹
bean標簽一般是在xml文件進行配置的,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"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
可在其中進行bean標簽的配置。
1.1、bean標簽的作用
bean標簽用於配置被spring容器管理的bean的信息
注意:bean標簽配置的bean的創建默認是調用無參數的構造方法,若沒有無參構造方法則不能創建成功。
1.2、bean標簽屬性
- id:給對象在容器中提供一個唯一標識。用於獲取對象。
- class:指定類的全限定名。用於反射創建對象。默認情況下調用無參構造函數。
- scope:指定對象的作用范圍。
- singleton:默認值,單例的(在整個容器中只有一個對象).
- prototype:多例的
- request:將Spring 創建的 Bean 對象存入到 request 域中.
- session:將Spring 創建的 Bean 對象存入到 session 域中.
- global session:WEB 項目中,應用在 Portlet 環境.如果沒有 Portlet 環境那么globalSession 相當於 session。
- init-method:指定類中的初始化方法名稱。
- destroy-method:指定類中銷毀方法名稱。比如DataSource的配置中一般需要指定destroy-method=“close”。
- lazy-init:ApplicationContext實現的默認行為就是在啟動時將所有 singleton bean進行實例化。lazy-init可以延遲初始化,設置
lazy-init="true"
使得Ioc容器在第一次需要bean的時候進行實例化。
示例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"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="wanger" class="com.luis.dto.Person"></bean>
<bean id="zhangsan" class="com.luis.dto.Person" init-method="init" destroy-method="over"></bean>
<bean id="lisi" class="com.luis.dto.Person" scope="prototype"></bean>
<bean id="lazy" class="com.luis.dto.Person" lazy-init="true"/></beans>
<bean name="address" class="com.luis.dto.Address"></bean>
</beans>
注意:id和name的區別
Bean標簽提供了兩種標識Bean的Attribute:id和name
- id用來標識bean,是唯一的,且只有一個,只允許以字母開頭,其后只能為字母或數字或”-“。
- name定義的是bean的alias,可以有多個,並可能與其他的bean重名,name允許特殊字符。
- 當多個重名的name同時存在時,先產生的bean會被后產生的bean覆蓋
- 當id和name的值相同,通過值獲取bean得到的是name對應的bean。
示例代碼如下:
<bean id="person" class="com.luis.dto.Student"></bean>
<bean name="person" class="com.luis.dto.Teacher"></bean>
<!-- factory.getBean(“person”)返回的是Teacher對象-->
若置bean的時候並沒有聲明ID屬性,則采用全類限定名作為bean的id,此時稱為匿名bean
<bean class="com.learnSpring.hellWorld"/>
<bean class="com.learnSpring.hellWorld"/>
<bean class="com.learnSpring.hellWorld"/>
如果存在多個class屬性都是一樣的匿名的Bean,則根據Spring讀取配置文件的順序生成id。
"com.learnSpring.hellWorld"
"com.learnSpring.hellWorld#0"
"com.learnSpring.hellWorld#1"
1.3、bena標簽作用范圍
我們可在xml文件中通過bean標簽的scope屬性指定作用域,其取值區別如下表:
作用域 | 描述 |
---|---|
singleton | 單例模式,singleton是默認的作用域,當定義Bean時沒有指定scope配置項,Bean的作用域被默認為singleton。singleton屬於單例模式,在整個系統上下文環境中,僅有一個Bean實例。 |
prototype | 原型模式,當一個Bean的作用域被定義prototype時,程序每次從IOC容器獲取的Bean都是一個新的實例。 |
request | http請求,bean作用於HTTP request生命周期,每個request有通過bean創建的實例。 |
session | 會話,bean作用於session生命周期。 |
global-session | 全局會話,bean作用於全局的session生命周期。 |
參考了:https://www.cnblogs.com/best/p/5727935.html
這里主要對單例對象與多例對象進行說明:
-
單例對象:
scope="singleton"
- 一個應用只用一個實例對象
- 生命周期與容器相關,當容器創建時對象產生,當對象銷毀時對象銷毀。
-
多例對象:
scope="prototype"
- 每次訪問對象時,都會重新創建對象實例。
- 生命周期與使用有關,當需要使用時創建對象,當對象長時間不使用,則被垃圾回收機制進行回收。
2、bean的實例化
bean有三種實例化方式:無參構造、靜態工廠、實例工廠
2.1、無參構造
默認情況下會根據無參構造方法進行對象的實例化。
若沒有無參構造方法則會創建失敗。
<bean id="wanger" class="com.luis.dto.Person"></bean>
2.2、靜態工廠
使用靜態工廠創建實例,其中:
- id 屬性:指定 bean 的 id,用於從容器中獲取
- class 屬性:指定靜態工廠的全限定類名
- factory-method 屬性:指定生產對象的靜態方法
<bean id="person" class="com.luis.factory.StaticFactory" factory-method="createPerson"/>
2.3、實例工廠
將工廠的創建交給Spring進行,使用工廠bean調用方法創建實例化對象。其中:
- factory-bean 屬性:用於指定實例工廠 bean 的 id。
- factory-method 屬性:用於指定實例工廠中創建對象的方法。
<bean id="instancFactory" class="com.luis.factory.PersonFactory"/>
<bean id="person" factory-bean="instancFactory" factory-method="createPerson"/>
二、DI配置
依賴注入(Dependency Injection)是 spring 框架核心 IoC 的具體實現。依賴指的是bean的屬性,包括:簡單類型(8種基本類型和String類型)的屬性、POJO類型的屬性、集合數組類型的屬性。我們通過控制反轉將實例化對象的交給IoC進行,但創建的對象沒有依賴,因而需要Spring維護依賴關系,即依賴注入。
1、依賴注入的方式
1.1、構造方法注入
使用類中的構造函數,給成員變量賦值,,通過在xml文件中的bean進行配置的方式給對象賦值。
構造方法注入涉及的標簽:
-
constructor-arg
-
index:指定參數在構造函數參數列表的索引位置
-
name:指定參數在構造函數中的名稱
-
value:它能賦的值是基本數據類型和 String 類型
-
ref:它能賦的值是其他 bean 類型,且必須是在配置文件中配置過的 bean
Spring配置文件xml中的配置如下:
- 使用參數名稱指定參數
<bean id="zhangsan" class="com.luis.dto.Person">
<constructor-arg name = "name" value ="張三"></constructor-arg>
<constructor-arg name = "age" value ="22"></constructor-arg>
</bean>
- 通過索引指定參數
<bean id="zhangsan" class="com.luis.dto.Person">
<constructor-arg index = "0" value ="張三"></constructor-arg>
<constructor-arg index = "1" value ="22"></constructor-arg>
</bean>
1.2、set方法注入
set方法注入又分為手動裝配方式注入和自動裝配方式注入。
- 手動裝配
通過bean標簽的子標簽property來完成,且需要在在類中指定setter方法。
- 自動裝配(注解方式進行),會在Spring的注解使用進行說明
- @Autowired:
- 作用一:查找實例,從spring容器中根據Bean的類型(byType)獲取實例。
- 作用二:賦值,將找到的實例,裝配給另一個實例的屬性值。
- 注意事項:一個Java類型在同一個spring容器中,只能有一個實例
- @Resource:
- 作用一:查找實例,從spring容器中根據Bean的名稱(byName)獲取實例。
- 作用二:賦值,將找到的實例,裝配給另一個實例的屬性值。
- @Autowired:
xml方式的示例代碼如下:
public class Address {
private String country;
private String city;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Address [country=" + country + ", city=" + city + "]";
}
}
Spring配置文件xml-ioc-01.xml中的配置如下:
<bean name="address" class="com.luis.dto.Address">
<property name = "country" value ="中國"></property>
<property name = "city" value ="西安"></property>
</bean>
可以簡寫為:
<bean id="address" class="com.luis.dto.Address" p:country="中國" p:city="西安"></bean>
1.3、p空間名稱注入
p名稱注入是set方法的一種簡寫方式,首先需引入p命名空間:
xmlns:p="http://www.springframework.org/schema/p"
p名稱空間的語法:p:屬性名 = ""
和 p:屬性名-ref = ""
上面的set注入可以簡寫為:
<bean id="address" class="com.luis.dto.Address" p:country="中國" p:city="西安"></bean>
若對象中有引用對象,則:
<bean name="address" class="com.luis.dto.Address"></bean>
<bean id="person" class="com.luis.dto.Person" p:pname="田七" p:age="22" p:address-ref="address"/>
2、不同屬性依賴注入
2.1、簡單類型
<!-- 構造方法注入 -->
<bean id="lisi" class="com.luis.dto.Person">
<constructor-arg name = "name" value ="李四"></constructor-arg>
<constructor-arg name = "age" value ="22"></constructor-arg>
</bean>
<!-- 構造方法注入 -->
<bean id="wangwu" class="com.luis.dto.Person">
<constructor-arg index = "0" value ="王五"></constructor-arg>
<constructor-arg index = "1" value ="22"></constructor-arg>
</bean>
<!-- set方法注入 -->
<bean name="address" class="com.luis.dto.Address">
<property name = "country" value ="中國"></property>
<property name = "city" value ="西安"></property>
</bean>
<!-- p空間名稱注入 -->
<bean id="address" class="com.luis.dto.Address" p:country="中國" p:city="西安"></bean>
2.2、引用類型
<bean id="address" class="com.luis.dto.Address">
<property name = "country" value ="中國"></property>
<property name = "city" value ="西安"></property>
</bean>
<!-- 構造方法注入 -->
<bean id="zhaoliu" class="com.luis.dto.Person">
<constructor-arg index = "0" value ="趙六"></constructor-arg>
<constructor-arg index = "1" value ="22"></constructor-arg>
<constructor-arg index = "2" ref ="address"></constructor-arg>
</bean>
<!-- set方法注入 -->
<bean id="tianqi" class="com.luis.dto.Person">
<property name = "name" value ="田七"></property>
<property name = "age" value ="22"></property>
<property name = "address" ref ="address"></property>
</bean>
<!-- p空間名稱注入 -->
<bean id="person" class="com.luis.dto.Person" p:pname="田七" p:age="22" p:address-ref="address"/>
2.3、集合類型
不同的集合類型,注入方式也有所區別:
1、數組或List集合
<bean id="person" class="com.luis.dto.Person">
<property name="arrs">
<list>
<!-- 如果集合內是簡單類型,使用value子標簽,如果是POJO類型,則使用bean標簽 -->
<value>張三</value>
<value>李四</value>
<!-- <bean></bean> -->
</list>
</property>
</bean>
2、Set集合
<property name="sets">
<set>
<!-- 如果集合內是簡單類型,使用value子標簽,如果是POJO類型,則使用bean標簽 -->
<value>張三</value>
<value>李四</value>
</set>
</property>
3、Map集合
<property name="map">
<map>
<entry key="張三" value="38"/>
<entry key="李四" value="38"/>
<entry key="王五" value="29"/>
</map>
</property>
4、Properties集合
<property name="pro">
<props>
<prop key="uname">root</prop>
<prop key="pass">123</prop>
</props>
</property>