【Spring筆記二】關於IOC和DI
IOC(Inversion of Control,反轉控制)
所謂的 IOC是指在程式設計中,例項不再由呼叫者來建立,而是由Spring容器來建立。簡單說就是建立物件由以前的程式設計師自己new 構造方法來呼叫,變成了交由Spring建立物件 。
以獲取物件的方式來進行比較 傳統的方式: 通過new 關鍵字主動建立一個物件 IOC方式 物件的生命週期由Spring來管理,直接從Spring那裡去獲取一個物件。 IOC是反轉控制 (Inversion Of Control)的縮寫,就像控制權從本來在自己手裡,交給了Spring。 打個比喻: 傳統方式:相當於你自己去菜市場new 了一隻雞,不過是生雞,要自己拔毛,去內臟,再上花椒,醬油,烤制,經過各種工序之後,才可以食用。 如:Category category=new Category()
用 IOC:相當於去館子(Spring)點了一隻雞,交到你手上的時候,已經五味俱全,你就只管吃就行了。
Category category= Spring生產
實際例子,建立專案,匯入jar包後
步驟一,準備pojo Category
package com.how2java.pojo; public class Category { 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; } private int id; private String name; }
步驟二,在src目錄下新建applicationContext.xml檔案 applicationContext.xml是Spring的核心配置檔案,通過關鍵字c即可獲取Category物件,該物件獲取的時候,即被注入了字串"category 1“到name屬性中
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean name="c" class="com.how2java.pojo.Category"> <property name="name" value="category 1" /> </bean> </beans>
步驟三 ,測試程式碼,演示通過spring獲取Category物件,以及該物件被注入的name屬性。
package com.how2java.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.how2java.pojo.Category;
public class TestSpring {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationContext.xml" });
Category c = (Category) context.getBean("c");
System.out.println(c.getName());
}
}
此時,觀察控制檯便可看到打印出了c的name屬性為category 1
DI(Dependency Injection,依賴注入)
它與控制反轉的含義相同,只不過這兩個稱呼是從兩個角度描述的同一個概念。可以這樣理解DI:如果一個物件A需要使用另一個物件B才能實現某個功能,這是就可以說A物件依賴於B物件,而Spring容器在建立A物件時,會自動將A物件需要的B物件注入到A物件中,此過程就是依賴注入。依賴注入的作用就是在使用Spring框架建立物件時,動態地將其所依賴的物件注入到Bean元件中。
結合上面程式碼來說 DI,我們在配置 XML的時候,對Category這個類中的 name 這個屬性進行了賦值,如下
<property name="name" value="category 1" />
我們可以稱為是屬性注入,而這個屬性注入是依賴於 Category這個類中的 setName() 這個方法。
在看看物件的注入
步驟一,準備一個新的類Product,Product類中有對Category物件的setter getter
package com.how2java.pojo;
public class Product {
private int id;
private String name;
private Category category;
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 Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
}
步驟二,修改applicationContext.xml ,在建立Product的時候注入一個Category物件 注意,這裡要使用ref來注入另一個物件
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean name="c" class="com.how2java.pojo.Category">
<property name="name" value="category 1" />
</bean>
<bean name="p" class="com.how2java.pojo.Product">
<property name="name" value="product1" />
<property name="category" ref="c" />
</bean>
</beans>
步驟三,建立測試類,檢視結果,通過Spring拿到的Product物件已經被注入了Category物件了
package com.how2java.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.how2java.pojo.Product;
public class TestSpring {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" });
Product p = (Product) context.getBean("p");
System.out.println(p.getName());
System.out.println(p.getCategory().getName());
}
}
用下面博主的話來概括IOC和DI就是,IOC 就是一種新的思想,而 DI 是這種新思想的具體實現。在Category中配置的 XML 我們就把它稱為是 IOC容器。
以下內容 作者:小異常 來源:CSDN 原文:https://blog.csdn.net/sun8112133/article/details/80139686
在 Spring中建立IOC容器的兩種方式(兩個介面)
1、BeanFactory
是 Spring 框架的基礎設施。
2、ApplicationContext(推薦使用)
面向使用Spring框架的開發者,是BeanFactory的子介面。
IOC 的目的 —— 解耦
其實我們使用 IOC 最大的目的是為了 “解耦”!! 提起 “解耦”,大家可能會聯想到 “高內聚,低耦合”,那我就帶大家再簡單回顧一下什麼是內聚什麼是耦合吧。。
高內聚,從字面上來看有聚精會神的意思,也就是儘可能的使一個模組或一個類再或者是一個方法只專注做好一件事。
低耦合,從字面上來看有藕斷絲連的意思,也就是儘可能的使每個模組之間或者每個類之間再或者是每個方法之間的關聯關係減少,這樣可以使各自盡可能的獨立,一個地方出錯,不會影響全部,更能提高程式碼的重用性。
“高內聚,低耦合”,用一句話概括就是寫的程式碼儘可能專一的完成一個任務,且各段程式碼儘量模組化互相獨立。
IOC 最主要的目的就是為了降低耦合度 —— 解耦,下面我用一個小例子帶大家體驗一下 IOC解耦。
1.人的介面:
public interface Person {
// 說話
public void say();
}
2.男人類(實現了人的介面):
public class Men implements Person {
@Override
public void say() {
System.out.println("我是男人!");
}
}
3.IOC 容器:
<bean id="men" class="com.briup.test.Men"></bean>
4.測試方法:
A、測試方法一(通過實現類):
public class Main {
public static void main(String[] args) {
// 獲取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
// 通過 實現類
Men men = (Men) ioc.getBean("men");
men.say();
}
}
B、測試方法二(通過介面):
public class Main {
public static void main(String[] args) {
// 獲取 IOC 容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
// 通過 介面
Person person = (Person) ioc.getBean("men");
person.say();
}
}
以上兩種方式(通過實現類和通過介面)都可以成功呼叫 say() 方法,測試方法一是通過 Men實現類 來呼叫 say() 方法,而測試方法二是通過 Person介面 來呼叫 say()方法,通過兩種方法的比較,測試方法二的耦合度要比測試方法一的耦合度低,可以達到解耦目的。
通常情況下,我們不能例項化介面,必須通過介面的實現類來呼叫方法,但是在 spring 中我們可以直接用介面,而不用考慮具體實現的類。