2017-04-20 80 views
2

有沒有人知道什麼技術春天使用在運行時實現依賴注入?它只是使用方面(AOP)還是更復雜?Spring如何在運行時實現依賴注入?

+0

看看這個[link](https://www.javatpoint.com/dependency-injection-in-spring)和[this one](https://www.quora.com/How-does-依賴注入,工作在春季)。 – ahoxha

回答

4

春天做了很多的事情,但是依賴注入本身實際上是一個令人驚訝的簡單機制。

它開始具有可用於注射類註冊表。 使用反射來檢查添加到此註冊表的類。 DI框架將查找相關的註釋和構造函數,以確定如何構造類的實例以及這些類可能需要的其他依賴項。

註冊表還跟蹤已創建的實例,使他們能夠重新使用。重用實例涉及範圍確定,確定何時可以重新使用實例。使用單例(Spring的默認值)實例可以不受限制地重複使用。

要創建具有依賴性類的一個實例,反射被用來創建一個實例。如果需要任何依賴項,那麼首先創建這些依賴項(如果尚未創建的話)可能會觸發大量遞歸創建實例。如果任何依賴項無法創建,或者有多個可能的候選項,則框架可能會拋出異常來指示配置中的問題。

一個簡單的例子,假設我們有一個Injector類作爲類這兩個註冊表和創建新實例的方法。

我們註冊了幾類:

injector.register(Database.class); 
injector.register(EmployeeDao.class); 

假設數據庫類沒有進一步的依賴關係,並EmployeeDao對數據庫的依賴:

class EmployeeDao { 
    @Inject Database db; 
} 

injector,通過反射的方式,知道EmployeeDaoDatabase有依賴性。當我們問injectorEmployeeDao實例會發生以下情況:

EmployeeDao employeeDao = injector.getInstance(EmployeeDao.class); 

1)如果已經存在的EmployeeDao一個實例,進行檢查,如果是,則返回。

2)如果不是,則檢查是否需要構造EmployeeDao,在這種情況下需要使用Database。該injector遞歸調用自己有:

Database database = injector.getInstance(Database.class); 

2A)同樣如果Database實例已經可以進行檢查,。

2b)爲了構造Database,所以injector調用Database.class.newInstance()並且保持跟蹤它不需要進一步的依賴關係。

2c)中,則返回Database實例。

3)隨着Database實例可用,injector現在可以構建EmployeeDaoEmployeeDao.class.newInstance() - 與反思的幫助下,現場database注入與Database實例。

4)返回現已完全注入的EmployeeDao實例。

這是獲得類的實例的相當直接的方式,但是這是DI框架如何像Spring一樣工作的核心。更高級的功能需要創建動態代理和使用AOP,但DI本身歸結爲使用反射自動構建實例。