1. 程式人生 > 其它 >Spring入門系列-IOC理論的推導

Spring入門系列-IOC理論的推導

IOC理論的推導

假設我們要寫一個user相關的業務

  1. UserDao介面
package com.dreamcold.dao;

public interface UserDao {

    public void getUser();
}

  1. UserDaoImpl實現類
package com.dreamcold.dao;

public class UserDaoImpl implements UserDao {


    public void getUser() {
        System.out.println("預設獲取使用者的資料");
    }
}

  1. UserService 業務介面
package com.dreamcold.service;

public interface UserService {
    public void getUser();
}

  1. 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();

    }
}

  1. 測試一下
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();
    }
}
  1. 對於Dao層中,假如我們要增加Mysql的實現
package com.dreamcold.dao;

public class UserDaoMysqlImpl implements UserDao {

    public void getUser() {
        System.out.println("Mysql實現獲取使用者資料");
    }
}

  1. 假如我們要使用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();

    }
}

  1. 但是我們發現,我們改了原來的程式碼假如使用者增加了Oracle的實現,每次使用者需求修改,我們都需要大量的修改程式,這不是一個優秀的程式應該做的
package com.dreamcold.dao;

public class UserDaoOracleImpl implements UserDao {


    public void getUser() {
        System.out.println("Oracle實現獲取使用者資料");
    }
}

  1. 我們這種情況下,還需要修改這裡,你的程式無法適應使用者的變更,使用者一旦需求變化,你就要改很多的東西,這樣其實是不成的
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();

    }
}

  1. 當我們將這裡改成對應的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();

    }
}

  1. 接下來,我們想用什麼實現,讓使用者自己選擇實現就可以了
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的本質

之前

  1. 使用者訪問的是業務層
  2. 每增加一個實現,主動權在業務層,無論怎麼增加實現,
  3. 控制權在程式設計師的手裡

之後

  1. 主動權在使用者那裡,使用者選擇在哪裡呼叫

控制反轉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)。

學習自連結:狂神說