Spring-IOC控制反轉的實現(XML配置方式)

IOC概念

IOC控制反轉(IoC,Inversion of Control), 是一個概念,是一種思想。控制反轉就是對對象控制權的轉移,從程序代碼自己反轉到了外部容器。把對象的建立、初始化、 銷燬等工做交給spring容器來作。由spring容器控制對象的生命週期。 DI依賴注入:Dependency Injection。 依賴注入DI是指程序運行過程當中,若須要調用另外一個對象協助時,無須在代碼中建立被調用者,而是依賴於外部容器,由外部容器建立後傳遞給程序。依賴注入是目前最優秀的解耦方式。依賴注入讓Spring的Bean之間以配置文件的方式組織在一塊兒,而不是以硬編碼的方式耦合在一塊兒的。 IoC與DI的關係 IoC是一個概念,是一種思想,其實現方式多種多樣。當前比較流行的實現方式之一是DI。 IOC:控制反轉, 將 new 的過程交給spring容器去處理java

XML配置方式

1、普通構造注入
  1. 建立Spring工程
  2. 建立Spring的XML配置文件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 http://www.springframework.org/schema/beans/spring-beans.xsd">
 </beans>
複製代碼

3.. 在Spring的配置文件中聲明User Bean: spring

在這裏插入圖片描述

<?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">
 	<!-- 在容器中註冊UserBean -->
 	<bean class="com.dpb.javabean.UserBean" id="userBean"></bean>
 </beans>
複製代碼

所謂的聲明,就是將本身的信息告訴Spring容器,例如id和class,Spring容器根據class,經過反射(默認使用的是無參構造方法)就能夠建立一個名爲user1的User對象。數組

  1. 初始化容器
public static void main(String[] args) {
   	//初始化Spring容器,當Spring容器初始化時,會自動加載配置文件,而後根據配置文件中的內容初始化Bean
   	ApplicationContext ac = 
   			new ClassPathXmlApplicationContext("application.xml");
   }
複製代碼

在這裏插入圖片描述
5. 初識化Spring容器以後,能夠看到User已經被建立出來了。 注意:上面這種初始化方式,要求User必須有一個無參構造方法,若是沒有無參構造方法,會拋出以下異常:
在這裏插入圖片描述
6.經過調用容器中的getBean方法能夠獲取Spring容器中的對象

public static void main(String[] args) {
		//初始化Spring容器,當Spring容器初始化時,會自動加載配置文件,而後根據配置文件中的內容初始化Bean
		ApplicationContext ac = 
				new ClassPathXmlApplicationContext("application.xml");
		// 去Spring容器中獲取一個UserBean對象
		UserBean user = ac.getBean("userBean", UserBean.class);
		System.out.println(user);
	}
複製代碼

在這裏插入圖片描述
7. 也能夠經過類型直接獲取一個Bean的實例
在這裏插入圖片描述

public static void main(String[] args) {
		//初始化Spring容器,當Spring容器初始化時,會自動加載配置文件,而後根據配置文件中的內容初始化Bean
		ApplicationContext ac = 
				new ClassPathXmlApplicationContext("application.xml");
		// 去Spring容器中獲取一個UserBean對象 經過類型直接獲取
		UserBean user = ac.getBean( UserBean.class);
		System.out.println(user);
	}
複製代碼

這種方式有潛在的隱患:若是Spring容器中有多個User的實例,此時就會報錯 bash

在這裏插入圖片描述

id和name的區別

實際開發過程當中咱們能夠忽略id和name的區別。能夠混合使用。經過getBean()方法均可以獲取,這個是個重載的方法。app

id="user1,user2,user3"
表示bean有一個名字,這個名字就是user1,user2,user3 
name="user1,user2,user3"
表示bean有多個名字,多個名字分別是user一、user2以及user3 
複製代碼

在同一配置文件中ID不要出現重複的。框架

BeanFactory和ApplicationContext的區別

/**
	 * ApplicationContext 方式加載
	 */
	@Test
	public void test1() {
		// 建立容器的同時 容器初始化,容器全部的bean建立完畢
		ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
		// 去Spring容器中獲取一個UserBean對象 經過類型直接獲取
		UserBean user = ac.getBean(UserBean.class);
		System.out.println(user);
	}
	
	/**
	 * BeanFactory 方式加載
	 */
	@Test
	public void test2() {
		// 建立容器對象,BeanFactory當調用getBean獲取響應對象是才建立對象
		BeanFactory bf = new XmlBeanFactory(new ClassPathResource("application.xml"));
		// 去Spring容器中獲取一個UserBean對象 經過類型直接獲取
		UserBean user = bf.getBean(UserBean.class);
		System.out.println(user);
	}
複製代碼

在這裏插入圖片描述
在這裏插入圖片描述

2、靜態工廠注入

建立靜態工廠類

/**
 * User 工廠類
 * @author dpb[波波烤鴨]
 *
 */
public class UserFactory {

	/**
	 * 必須是static方法
	 * @return
	 */
	public static UserBean getInstance(){
		return new UserBean();
	}
}
複製代碼

application.xml文件中註冊ide

<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 class="com.dpb.factory.UserFactory" factory-method="getInstance" id="user2"/>
</beans>
複製代碼

獲取相應的實例 測試

在這裏插入圖片描述

應用場景

在一些第三方框架使用過程 中,可能不得不使用靜態工廠注入或者實例工廠注入。ui

HttpUrlConnection
HttpClient
OkHttp
複製代碼

這裏以OkHttp爲例說明爲什麼須要靜態工廠注入 因爲OkHttpClient須要經過Builder進行建立,所以沒法直接使用構造方法注入。此時能夠經過靜態工廠注入。this

3、動態工廠注入

建立動態工廠類

/**
 * User 工廠類
 * @author dpb[波波烤鴨]
 *
 */
public class UserFactory {

	/**
	 * 動態工廠方式獲取
	 * 普通方法
	 * @return
	 */
	public  UserBean getInstance(){
		return new UserBean();
	}
}
複製代碼

application.xml註冊

<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 -->
	<bean class="com.dpb.factory.UserFactory" id="userFactory"/>
	<!-- 從工廠中獲取UserBean對象 -->
	<bean id="user" factory-bean="userFactory" factory-method="getInstance"/>
</beans>
複製代碼

獲取實例

在這裏插入圖片描述

4、屬性注入

屬性注入主要是指如何給對象中的屬性賦值

構造注入

建立有參構造方法,同時必須提供無參構造方法

在這裏插入圖片描述

application.xml中注入

<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">
	<!-- 註冊UserBean -->
	<bean class="com.dpb.javabean.UserBean" id="userBean">
		<!-- 經過構造注入設置 -->
		<constructor-arg name="id" value="1"/>
		<constructor-arg name="name" value="波波烤鴨"/>
		<constructor-arg name="age" value="18"/>
	</bean>
</beans>
複製代碼

還能夠經過下標定位參數

<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">
	<!-- 註冊UserBean -->
	<bean class="com.dpb.javabean.UserBean" id="userBean">
		<!-- 經過構造注入設置 經過index 定位設置 -->
		<constructor-arg index="0" value="1"/>
		<constructor-arg index="1" value="波波烤鴨"/>
		<constructor-arg index="2" value="18"/>
	</bean>
</beans>
複製代碼

測試結果

在這裏插入圖片描述

設值注入

Java對象中提供對應的setter方法

有參構造方法不是必須的了,無參方法是必須的!!! set方法注入就是利用對象屬性的set方法給屬性賦值,實際上,至關於首先使用無參構造方法建立一個Book對象,而後調用對象中的set方法給各個屬性賦值。

/**
 * 
 * @author dpb[波波烤鴨]
 *
 */
public class UserBean {

	private int id;
	
	private String name;
	
	private int age;
	
	/**
	 * 無參構造方法
	 */
	public UserBean() {
		System.out.println("無參構造方法");
	}


	public int getId() {
		return id;
	}

	/**
	 * 設值注入 必須提供對應的setter方法
	 * @param id
	 */
	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	/**
	 * 設值注入 必須提供對應的setter方法
	 * @param name
	 */
	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	/**
	 * 設值注入 必須提供對應的setter方法
	 * @param age
	 */
	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "UserBean [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	public void say(){
		System.out.println("hello ...");
	}
}
複製代碼

application.xml配置

<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">
	<!-- 註冊UserBean -->
	<bean class="com.dpb.javabean.UserBean" id="userBean">
		<!--經過設值注入的方式注入  -->
		<property name="id" value="2"/>
		<property name="name" value="bobo烤鴨"/>
		<property name="age" value="32"/>
	</bean>
</beans>
複製代碼

測試

在這裏插入圖片描述

p名稱空間注入

p名稱空間注入本質上仍是set方法注入,只是寫法不一樣(注意:p名稱空間注入,須要有無參構造方法)。

JavaBean對象

/**
 * p名稱空間注入
 * @author dpb[波波烤鴨]
 *
 */
public class Person {

	private int id;
	private String name;
	private String address;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", address=" + address + "]";
	}
}
複製代碼

application.xml配置

在這裏插入圖片描述

<!-- 註冊 Person -->
<bean id="person" class="com.dpb.javabean.Person" p:id="3" p:name="鄧澎波" p:address="深圳"/>
複製代碼

測試

在這裏插入圖片描述

這種注入方式瞭解便可,實際開發中使用較少。

對象注入

對象能夠經過構造方法、set方法或者p名稱空間注入,步驟以下:

Student類和Cat類

/**
 * 學生
 * @author dpb[波波烤鴨]
 *
 */
public class Student {

	private int id;
	private String name;
	// 擁有的 cat
	private Cat cat;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Cat getCat() {
		return cat;
	}
	public void setCat(Cat cat) {
		this.cat = cat;
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", cat=" + cat + "]";
	}
	
}
複製代碼
/**
 * 貓
 * @author dpb[波波烤鴨]
 *
 */
public class Cat {

	private int id;
	
	private String color;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	@Override
	public String toString() {
		return "Cat [id=" + id + ", color=" + color + "]";
	}
	
}
複製代碼

application.xml配置

<!-- 配置 cat -->
	<bean id="catId" class="com.dpb.javabean.Cat">
		<property name="id" value="1"/>
		<property name="color" value="red"></property>
	</bean>
	<!-- 配置 student對象 -->
	<bean class="com.dpb.javabean.Student">
		<property name="id" value="10"/>
		<property name="name" value="波波烤鴨"/>
		<!-- 對象注入 -->
		<property name="cat" ref="catId"></property>
	</bean>
複製代碼

測試

在這裏插入圖片描述

數組和集合注入

數組和集合的注入方式是一致的,不管是基本數據類型仍是一個引用,注入方式都是同樣。 首先聲明一個對象,對象中包含集合和數組

對象中添加對應的類型數據

在這裏插入圖片描述
在這裏插入圖片描述

application.xml注入

<!-- 配置 student對象 -->
	<bean class="com.dpb.javabean.Student">
		<property name="id" value="10"/>
		<property name="name" value="波波烤鴨"/>
		<!-- 對象注入 -->
		<property name="cat" ref="catId"></property>
		<!-- List集合注入 -->
		<property name="games">
			<list>
				<value>LOL</value>
				<value>DNF</value>
				<value>CS</value>
			</list>
		</property>
		<!-- 數組注入 -->
		<property name="books">
			<list>
				<bean class="com.dpb.javabean.Book">
					<property name="id" value="1001"/>
					<property name="bookName" value="西遊記"/>
				</bean>
				<bean class="com.dpb.javabean.Book">
					<property name="id" value="1002"/>
					<property name="bookName" value="紅樓夢"/>
				</bean>
			</list>
		</property>
	</bean>
複製代碼

測試

在這裏插入圖片描述

Map注入

聲明Map屬性,注意屬性的key和value的數據類型須要提早定義好,而後在xml文件中直接使用(xml文件中配置時,key和屬性的值必需要知足聲明的要求,不然就會出錯)。

對象中添加 Map屬性

在這裏插入圖片描述

配置文件注入

<property name="score">
	<map>
		<entry key="數學" value="99"/>
		<entry key="英語" value="78"/>
		<entry key="化學" value="84"/>
	</map>
</property>
複製代碼

測試

在這裏插入圖片描述

props注入

properties注入與map注入相似

對象中添加properties屬性

在這裏插入圖片描述

配置文件中注入

<property name="props">
	<props>
		<prop key="userName">admin</prop>
		<prop key="password">123</prop>
	</props>
</property>
複製代碼

測試

在這裏插入圖片描述
相關文章
相關標籤/搜索