Spring 基於 XML 的 IOC依賴注入的 細節[掌握哦!!!
Spring之 IOC的繼續—bean標籤 --依賴注入 DI— 02
BeanFactory 和 ApplicationContext 的區別
BeanFactory 才是 Spring 容器中的頂層介面。ApplicationContext 是它的子介面。BeanFactory 和 ApplicationContext 的區別:建立物件的時間點不一樣。ApplicationContext:只要一讀取配置檔案,預設情況下就會建立BeanFactory:什麼使用什麼時候建立物件。
ApplicationContext 介面的實現類ClassPathXmlApplicationContext:它是從類的根路徑下載入配置檔案 推薦使用這種FileSystemXmlApplicationContext:它是從磁碟路徑上載入配置檔案,配置檔案可以在磁碟的任意位置。AnnotationConfigApplicationContext:當我們使用註解配置容器物件時,需要使用此類來建立 spring 容器。
spring 的依賴注入
依賴注入的概念
依賴注入:Dependency Injection。它是 spring 框架核心 ioc 的具體實現。
我們的程式在編寫時,通過控制反轉,把物件的建立交給了 spring,但是程式碼中不可能出現沒有依賴的情況。
ioc 解耦只是降低他們的依賴關係,但不會消除。例如:我們的業務層仍會呼叫持久層的方法。
那這種業務層和持久層的依賴關係,在使用 spring 之後,就讓 spring 來維護了。
編碼程式呈現----------》
建立 maven的 module
maven 的 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
com.fhw
fhw01_05DI
1.0-SNAPSHOT
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
bean.xml檔案
<?xml version="1.0" encoding="UTF-8"?>
<!--constructor-arg建構函式 的
優勢 : 必須要注入所有的 引數 否則 失敗
弊端:用不到的引數也要提供 死板 -->
<constructor-arg name="name" value="fhw"></constructor-arg>
<constructor-arg name="age" value="20"></constructor-arg>
<constructor-arg name="birthday" ref="date"></constructor-arg>
<!-- DI :之set 注入===常用的方式
標籤: property 在bean 裡
property 屬性:
name: 最直接 最常用 : 寫上 set的方法名稱( 不寫set這幾個字 , 首字母就不大寫了
由於是編輯器 生成 的一舉 的就是屬性名 所以就 直接的 =====》寫屬性名即可 )
變數名稱=======》這是指定 引數的賦值
value:要注入 的元素
ref: 引用關聯的bean物件
優勢: 沒有明確的限制 ,直接用預設建構函式
劣勢:成員 必須有值 , 無法保持 一定注入 獲取物件時 有時set 沒有執行
呼叫物件的時候 可能 通過建構函式 已用完了,
-->
<!-- 複雜集合 的DI
array List Set :的標籤可以互換
Map 與 properties 結構 相同 標籤可以互換
概括為:2 種 記好 單列 或 雙列 各自的標籤 可以互換
-->
<bean id="DI_Container" class="com.fhw.service.impl.fhw03_DI_Container">
<!--值資料 單列集合 -->
<property name="myStr">
<array>
<value>fff</value>
<value>hhh</value>
<value>www</value>
</array>
</property>
<property name="myList">
<list>
<value>fff</value>
<value>hhh</value>
<value>www</value>
</list>
</property>
<property name="mySet">
<set>
<value>fff</value>
<value>hhh</value>
<value>www</value>
</set>
</property>
<!-- 對映關係資料集合==== 雙列集合-->
<property name="myMap">
<map ><!-- map的 2個方式 -->
<entry key="map1" value="mmm" ></entry>
<entry key="map2"><value>aaa</value></entry>
</map>
</property>
<property name="myPros">
<props ><!-- Properties的 方式 -->
<prop key="Properties01">ppp</prop>
<prop key="Properties02">rrr</prop>
</props>
</property>
</bean>
service裡的程式碼
構造方法的注入 方式*
package com.fhw.service.impl;
import java.util.Date;
public class fhw01_DI_constructor {
private String name ;
private int age;
private Date birthday;
/*注入 注意的就是 資料型別 type : 基本資料 int 字串String ,其他bean型別 date */
public fhw01_DI_constructor (String name,Integer age,Date birthday){
this.name=name;
this.age=age;
this.birthday=birthday;
}
public void saveAccount() {
System.out.println("構造方法 的方式執行了"+name+"======"+age+"====="+birthday);
}
}
set方法的方式
public class fhw02_DI_set {
private String name ;
private int age;
private Date birthday;
/*注入 注意的就是 資料型別 type : 基本資料 int 字串String ,其他bean型別 date /
/ 注入 只需要 set方法即可 */
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public void setDI() {
System.out.println("set 方法執行了"+name+"======"+age+"====="+birthday);
}
}
集合容器的方式
package com.fhw.service.impl;
import java.util.*;
public class fhw03_DI_Container {
private String[] myStr;
private List myList;
private Set mySet;
private Map<String, String> myMap;
private Properties myPros;
public void setMyStr(String[] myStr) {
this.myStr = myStr;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public void setMyPros(Properties myPros) {
this.myPros = myPros;
}
public void myCollection() {
System.out.println("容器陣列:"+ Arrays.toString(myStr));
System.out.println("容器list:"+myList);
System.out.println("容器Set:"+mySet);
System.out.println("容器Map:"+myMap);
System.out.println("容器Properties:"+myPros);
}
}
測試
package com.fhw.ui;
import com.fhw.service.impl.fhw01_DI_constructor;
import com.fhw.service.impl.fhw02_DI_set;
import com.fhw.service.impl.fhw03_DI_Container;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Client {
/**
*
-
@param args
*/
public static void main(String[] args) {//獲取 spring 的核心容器物件: 引數就是 bean.xml
ApplicationContext ac=new ClassPathXmlApplicationContext(“bean.xml”);
// ApplicationContext acFile= new FileSystemXmlApplicationConext("");
fhw01_DI_constructor as = (fhw01_DI_constructor)ac.getBean(“fhw01”);//要強轉
// IAccountDao adao=ac.getBean(“accountDao”,IAccountDao.class);
as.saveAccount();
fhw02_DI_set set1=(fhw02_DI_set)ac.getBean(“DI_set”);
set1.setDI();
fhw03_DI_Container container = (fhw03_DI_Container)ac.getBean(“DI_Container”);
container.myCollection();
}
}
附 : 使用 p 名稱空間注入資料(本質還是呼叫 set 方法)
此種方式是通過在 xml 中匯入 p 名稱空間,使用 p:propertyName 來注入資料,它的本質仍然是呼叫類中的set 方法實現注入功能。Java 類程式碼:/*** 使用 p 名稱空間注入,本質還是呼叫類中的 set 方法*/public class AccountServiceImpl4 implements IAccountService {private String name;private Integer age;private Date birthday;public void setName(String name) {this.name = nam
}public void setAge(Integer age) {this.age = age;}public void setBirthday(Date birthday) {this.birthday = birthday;}@Overridepublic void saveAccount() {System.out.println(name+","+age+","+birthday);}
xml 檔案程式碼:ans xmlns=“http://www.springframework.org/schema/beans” xmlns:p=“http://www.springframework.org/schema/
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