Spring入門系列-IOC理論的推導
IOC理論的推導
假設我們要寫一個user相關的業務
- UserDao介面
package com.dreamcold.dao;
public interface UserDao {
public void getUser();
}
- UserDaoImpl實現類
package com.dreamcold.dao;
public class UserDaoImpl implements UserDao {
public void getUser() {
System.out.println("預設獲取使用者的資料");
}
}
- UserService 業務介面
package com.dreamcold.service;
public interface UserService {
public void getUser();
}
- UserServiceImpl 業務實現類
package com.dreamcold.service; import com.dreamcold.dao.UserDao; import com.dreamcold.dao.UserDaoImpl; public class UserSeviceImpl implements UserService { private UserDao userDao=new UserDaoImpl(); public void getUser(){ userDao.getUser(); } }
- 測試一下
import com.dreamcold.service.UserService;
import com.dreamcold.service.UserSeviceImpl;
public class MyTest {
public static void main(String[] args) {
UserService userService=new UserSeviceImpl();
userService.getUser();
}
}
- 對於Dao層中,假如我們要增加Mysql的實現
package com.dreamcold.dao; public class UserDaoMysqlImpl implements UserDao { public void getUser() { System.out.println("Mysql實現獲取使用者資料"); } }
- 假如我們要使用Mysql來實現dao層使用者資料的獲取
package com.dreamcold.service;
import com.dreamcold.dao.UserDao;
import com.dreamcold.dao.UserDaoImpl;
import com.dreamcold.dao.UserDaoMysqlImpl;
public class UserSeviceImpl implements UserService {
private UserDao userDao=new UserDaoMysqlImpl();//這裡改成mysql的對應實現
public void getUser(){
userDao.getUser();
}
}
- 但是我們發現,我們改了原來的程式碼假如使用者增加了Oracle的實現,每次使用者需求修改,我們都需要大量的修改程式,這不是一個優秀的程式應該做的
package com.dreamcold.dao;
public class UserDaoOracleImpl implements UserDao {
public void getUser() {
System.out.println("Oracle實現獲取使用者資料");
}
}
- 我們這種情況下,還需要修改這裡,你的程式無法適應使用者的變更,使用者一旦需求變化,你就要改很多的東西,這樣其實是不成的
package com.dreamcold.service;
import com.dreamcold.dao.UserDao;
import com.dreamcold.dao.UserDaoImpl;
import com.dreamcold.dao.UserDaoMysqlImpl;
import com.dreamcold.dao.UserDaoOracleImpl;
public class UserSeviceImpl implements UserService {
private UserDao userDao=new UserDaoOracleImpl();//這裡改成oracle的對應實現
public void getUser(){
userDao.getUser();
}
}
- 當我們將這裡改成對應的setter方法
package com.dreamcold.service;
import com.dreamcold.dao.UserDao;
import com.dreamcold.dao.UserDaoImpl;
import com.dreamcold.dao.UserDaoMysqlImpl;
import com.dreamcold.dao.UserDaoOracleImpl;
public class UserSeviceImpl implements UserService {
private UserDao userDao;
//這裡的setter方法,利用set來實現動態值的注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void getUser(){
userDao.getUser();
}
}
- 接下來,我們想用什麼實現,讓使用者自己選擇實現就可以了
import com.dreamcold.dao.UserDaoOracleImpl;
import com.dreamcold.service.UserService;
import com.dreamcold.service.UserSeviceImpl;
public class MyTest {
public static void main(String[] args) {
UserSeviceImpl userService=new UserSeviceImpl();
userService.setUserDao(new UserDaoOracleImpl()); //想用oracle的實現
userService.getUser();
}
}
-
在我們原來的業務中,使用者的需求可能會影響我們原來的diam,我們需要根據使用者的需求去修改原始碼,如果程式的量非常大,修改程式碼的代價十分的昂貴,我們僅僅使用set介面實現,已經發生了革命性的變化,原來是程式主動建立物件,控制權在程式設計師手上,但是使用了set注入後,程式不再具有主動性,而是變成了被動的接受物件!
-
這種思想程式設計師不用再去管理物件的建立了,而是變成了被動的接受物件。
-
系統的耦合性大大降低,可以專注於擴充套件於業務
專案結構
IOC的本質
之前
- 使用者訪問的是業務層
- 每增加一個實現,主動權在業務層,無論怎麼增加實現,
- 控制權在程式設計師的手裡
之後
- 主動權在使用者那裡,使用者選擇在哪裡呼叫
控制反轉IoC(Inversion of Control),是一種設計思想,DI(依賴注入)是實現IoC的一種方法,也有人認為DI只是IoC的另一種說法。沒有IoC的程式中 , 我們使用面向物件程式設計 , 物件的建立與物件間的依賴關係完全硬編碼在程式中,物件的建立由程式自己控制,控制反轉後將物件的建立轉移給第三方,個人認為所謂控制反轉就是:獲得依賴物件的方式反轉了。
IoC是Spring框架的核心內容,使用多種方式完美的實現了IoC,可以使用XML配置,也可以使用註解,新版本的Spring也可以零配置實現IoC。
Spring容器在初始化時先讀取配置檔案,根據配置檔案或元資料建立與組織物件存入容器中,程式使用時再從Ioc容器中取出需要的物件。
採用XML方式配置Bean的時候,Bean的定義資訊是和實現分離的,而採用註解的方式可以把兩者合為一體,Bean的定義資訊直接以註解的形式定義在實現類中,從而達到了零配置的目的。
控制反轉是一種通過描述(XML或註解)並通過第三方去生產或獲取特定物件的方式。在Spring中實現控制反轉的是IoC容器,其實現方法是依賴注入(Dependency Injection,DI)。
學習自連結:狂神說