控制反轉(IoC)-解析與實現


控制反轉(Inversion of Control)縮寫:IoC是面向對象編程中框架級別里的一個重要的概念,

可以說Spring框架的核心就是基於IoC原理的。

 

這個概念到底是什么呢?

這么講吧,一個系統的運作肯定不是簡單的幾個類就可以實現的,它往往需要多個類的合作來實現業務邏輯

。這就使得每個對象都需要與其合作的對象具有相互的關系(依賴關系)。在早前編程中所需要的依賴對象

是通過自身去創建得到的,而現在是通過一個容器來統一管理這些依賴關系。在這整個過程中,對象獲得其他對象引用的方式其實就是IoC。

 

IoC的本質是什么?

控制權的轉移。IoC原理是基於面向對象中的設計原則的The Hollywood Principle:Don't call us,we'll call you(別找我,我會來找你的)。

可以這樣講,所有組件的初始化和調用都是由容器負責。在傳統實現中類之間的關系是由類自己控制的(需要使用其他類時就自己創建),

但是在IoC中,組件處在容器中,由容器統一管理和調度。這就是"控制反轉"的概念所在:控制權由應用代碼轉移到了容器中,即控制權的轉移。

 

那如何實現IoC這種思想的呢?

實現IoC思想的方式主要有兩種:依賴注入和依賴查找。

下面就以依賴注入為例講解一下:

 1 1.先定義一個部門接口:
 2 
 3 public interface IDepartService {
 4     //通過員工編號獲得部門名字
 5     public String getDepartNameByUser(int userId);
 6 }
 7 
 8 2.實現該接口:
 9 public class DepartServiceImpl implements IDepartService {
10 
11     @Override
12     public String getDepartNameByUser(int userId) {
13         if(userId==1){
14             return "IT部門";
15         }
16         return "";
17     }
18 }
19 3.定義一個用戶類,該類中要維持部門對象的引用:
20 
21 public class UserServiceImpl {
22     private IDepartService departService;
23     
24     public void printInfo(int userId){
25         System.out.print(getUserName(userId));
26         System.out.println(departService.getDepartNameByUser(userId));
27     }
28     
29     public String getUserName(int userId){
30         if(userId==1){
31             return "張三 ";
32         }
33         return "";
34     }
35 }

在用戶類中,我們沒有看到關於創建DepartService對象的語句。這里面我們沒有采用常見的set注入或者構造方法注入,

而是采用反射的方法直接注入並執行的,要實現這個效果的話,我們需要定義一個容器,來管理他們的關系。

4.定義容器,我們在容器中先獲取配置文件:
public class Container {
    ......
    private void loadConfig() {
        // TODO Auto-generated method stub
        InputStream is = Container.class.getResourceAsStream("/ioc.properties");
        properties = new Properties();
        try {
            properties.load(is);
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    public Object get(String name) {
        String className = (String) properties.get(name);
        return Class.forName(className).newInstance();
            ......
    }

    public void inject(Object obj) {
        Field[] fields = obj.getClass().getDeclaredFields();
            ......
            for (Field field : fields) {
                field.setAccessible(true);
                field.set(obj, get(field.getName()));
            }
           ......
    }
}
在上述中,首先獲取配置文件中已配置好的依賴關系,然后采用反射技術根據依賴關系進行創建相應的對象
5.其中ioc.properties的內容為:
departService=com.service.impl.DepartServiceImpl
6.查看入口方法:
public static void main(String[] args) {
        UserServiceImpl user=new UserServiceImpl();
    
        Container container=new Container();
        container.inject(user);
        user.printInfo(1);
}

7.查看結果:

總結:可以說IoC這個思想是一個很偉大的思想,現在很多大神甚至將它歸為GoF中(因為IoC出現的比較晚,錯過了GoF“四人組”的《Design Patterns: Elements of Reusable Object-Oriented Software》)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM