<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # Spring – 控制反轉與依賴注入 > 原文: [https://howtodoinjava.com/spring-core/spring-ioc-vs-di/](https://howtodoinjava.com/spring-core/spring-ioc-vs-di/) 在軟件工程中,[**控制反轉**](https://en.wikipedia.org/wiki/Inversion_of_control)(IoC)是一種編程技術,其中對象耦合在運行時由匯編程序對象綁定,并且在編譯時使用靜態分析通常是未知的 。 在這個 Spring 教程中,通過示例了解 IoC 和依賴注入在 Spring 中的區別。 ## 1\. 什么是控制反轉(IoC) 在傳統編程中,業務邏輯的流程由靜態分配給彼此的對象確定。 通過控制的反轉,該流程取決于由匯編程序實例化的對象圖,并且通過抽象定義對象交互使之成為可能。 綁定過程是通過依賴項注入實現的,盡管有些人認為使用服務定位器還可以提供控制反轉。 **控制反轉作為設計準則**具有以下目的: 1. 某個任務的執行與實現之間存在脫鉤。 2. 每個模塊都可以專注于其設計目的。 3. 模塊不假設其他系統在做什么,而是依賴其合同。 4. 更換模塊對其他模塊沒有副作用。 ## 2\. 什么是依賴注入(DI) IoC 是一種設計示例,其目標是對應用程序的目標組件提供更多控制,使這些組件可以完成工作。 依賴注入是一種模式,用于創建其他對象依賴的對象實例,而在編譯時不知道將使用哪個類來提供該功能。 IoC 依賴于依賴項注入,因為需要一種機制來激活提供特定功能的組件。 這兩個概念以這種方式一起工作,以允許編寫更加靈活,可重用和封裝的代碼。 因此,它們是設計面向對象解決方案中的重要概念。 ## 3\. 如何實現 IoC 在面向對象的編程中,有幾種基本技術可以實現控制反轉。 這些是: 1. 使用工廠模式 2. 使用服務定位器模式 3. 使用以下任何給定類型的**依賴項注入**: * 構造函數注入 * setter 注入 * 接口注入 ## 4\. Spring 的控制反轉 `org.springframework.beans`和`org.springframework.context`軟件包為 Spring Framework 的 IoC 容器提供了基礎。 [`BeanFactory`](https://docs.spring.io/spring/docs/1.2.x/javadoc-api/org/springframework/beans/factory/BeanFactory.html) 接口提供了一種高級配置機制,能夠管理任何性質的對象。 [`ApplicationContext`](https://docs.spring.io/spring/docs/2.5.5/javadoc-api/org/springframework/context/ApplicationContext.html) 接口建立在`BeanFactory`的基礎上(它是一個子接口),并添加了其他功能,例如與 Spring 的 AOP 功能的集成更加容易,消息資源處理(用于國際化), 事件傳播以及用于 Web 應用程序的特定于應用程序層的上下文,例如`WebApplicationContext`。 `BeanFactory`是 Spring IoC 容器的實際表示,該容器負責容納和管理上述 bean。 `BeanFactory`接口是 Spring 中的中央 IoC 容器接口。 [![container-magic](https://img.kancloud.cn/4c/fd/4cfdf2abc22a6c5311cc53ef8d565935_498x296.jpg)](https://howtodoinjava.files.wordpress.com/2013/03/container-magic.png) `BeanFactory`接口有多種實現。 最常用的`BeanFactory`實現是`XmlBeanFactory`類。 其他常用的類是`XmlWebApplicationContext`。 根據 bean 的定義,工廠將返回所包含對象的獨立實例(原型設計模式),或者返回單個共享實例(單例設計模式的替代方案,其中實例是作用域中的單例工廠)。將返回哪種類型的實例取決于 bean 工廠的配置:API 是相同的。 在深入研究**依賴項注入類型**之前,讓我們首先確定在 spring 框架中創建 bean 的方法,因為它將有助于理解下一部分的內容。 ## 5\. 如何在 Spring 中創建 bean Bean 定義可以視為創建一個或多個實際對象的方法。 詢問時,容器將查看命名 bean 的配方,并使用該 bean 定義封裝的配置元數據來創建(或獲取)實際對象。 #### 5.1. 使用構造函數 當使用構造函數方法創建 bean 時,所有普通類都可以被 Spring 使用并與之兼容。 也就是說,正在創建的類不需要實現任何特定的接口或以特定的方式進行編碼。 僅指定 bean 類就足夠了。 使用基于 XML 的配置元數據時,您可以像這樣指定 bean 類: `beans.xml` ```java <bean id="exampleBean"/> ``` #### 5.2. 使用靜態工廠方法 在定義要使用靜態工廠方法創建的 bean 以及指定包含靜態工廠方法的類的`class`屬性時,需要另一個名為`factory-method`的屬性來指定工廠方法本身的名稱。 `beans.xml` ```java <bean id="exampleBean" factory-method="createInstance"/> ``` Spring 希望能夠調用此方法并返回一個活動對象,從那時起,該對象將被視為通常是通過構造函數創建的。 #### 5.3. 使用實例工廠方法 以類似于通過靜態工廠方法進行實例化的方式,使用實例工廠方法進行實例化是調用容器中現有 bean 的工廠方法來創建新 bean。 `beans.xml` ```java <bean id="myFactoryBean" class="..."> <bean id="exampleBean" factory-bean="myFactoryBean" factory-method="createInstance"></bean> ``` ## 6\. Spring 的依賴注入 依賴注入(DI)的基本原理是,對象只能通過構造函數參數,工廠方法的參數或在對象實例從工廠方法構造或返回后設置的屬性來定義其依賴關系。 然后,容器的工作是在創建 bean 時實際注入那些依賴項。 從根本上講,這是相反的概念,因此被稱為控制反轉(IoC)。 #### 6.1. 二次注入 通過調用無參數構造函數或無參數靜態工廠方法以實例化 bean 之后,在 bean 上調用 setter 方法,可以實現基于 setter 的 DI。 `TestSetterDI.java` ```java public class TestSetterDI { DemoBean demoBean = null; public void setDemoBean(DemoBean demoBean) { this.demoBean = demoBean; } } ``` #### 6.2. 構造函數注入 基于構造函數的 DI 是通過調用具有多個參數(每個參數代表一個協作者)的構造函數來實現的。 另外,調用帶有特定參數的靜態工廠方法來構造 Bean 幾乎是等效的,本文的其余部分將類似地考慮構造函數的參數和靜態工廠方法的參數。 `ConstructorDI.java` ```java public class ConstructorDI { DemoBean demoBean = null; public TestSetterDI (DemoBean demoBean) { this.demoBean = demoBean; } } ``` #### 6.3. 接口注入 在這種方法中,我們實現了 IOC 框架的接口。 IOC 框架將使用接口方法將對象注入到主類中。 當您需要某種不適用于放置在屬性中的邏輯時,使用這種方法更為合適。 如日志支持。 ```java public void SetLogger(ILogger logger) { _notificationService.SetLogger(logger); _productService.SetLogger(logger); } ``` ## 7\. 面試題 #### 7.1. 組件和服務之間有什么區別? 組件是一整套軟件,旨在由不受組件編寫者控制的應用程序直接使用。 “不更改”表示使用中的應用程序不會更改組件的源代碼,盡管它們可能會通過以組件編寫者允許的方式擴展組件來更改組件的行為。 服務與組件相似,供外部應用程序使用。 主要區別在于要在本地使用的組件(請考慮 jar 文件,程序集,dll 或源導入)。 服務將通過同步或異步的某個遠程接口(例如,Web 服務,消息系統,RPC 或套接字)遠程使用。 #### 7.2. DI 與服務定位器模式有何不同? 依賴項注入器的主要好處是,它允許根據環境和使用情況插入合適的服務實現。 注入不是打破這種依賴的唯一方法,另一種方法是使用服務定位器。 服務定位器的基本思想是擁有一個對象,該對象知道如何掌握應用程序可能需要的所有服務。 然后,它將掃描所有此類服務,并將它們存儲為單例注冊表。 當要求提供服務實現時,請求者可以使用令牌查詢注冊表并獲取適當的實現。 通常,這些注冊表是通過一些配置文件填充的。 關鍵區別在于,使用服務定位器時,服務的每個用戶都對定位器具有依賴。 定位器可以隱藏對其他實現的依賴關系,但是您確實需要查看定位器。 #### 7.3. 使用哪個服務更好(即服務定位器或依賴項注入)? 嗯,正如我已經說過的,關鍵區別在于,使用服務定位器,服務的每個用戶都對定位器有依賴。 這意味著您必須在輸入和輸出切面了解服務定位器的詳細信息。 因此,實際上成為選擇哪種模式的決定因素。 如果維護注冊表信息既簡單又必要,則可以使用服務定位器,或者直接使用依賴項注入,因為它不會使服務用戶感到任何先決條件。 #### 7.4. 構造函數注入或 setter 注入哪個更好? 在 setter 和構造函數注入之間進行選擇很有趣,因為它反映了面向對象編程的一個更普遍的問題 – 如果您在構造函數或 setter 中填充字段。 帶參數的構造函數可讓您清楚地說明在明顯的位置創建有效對象的含義。 如果執行此操作的方法不止一種,請創建多個顯示不同組合的構造函數。 構造函數初始化的另一個優點是,您可以通過不提供設置器來清楚地隱藏任何不可變的字段。 我認為這很重要-如果某些事情不應該改變,那么缺少二傳手就可以很好地傳達這一點。 如果使用 setter 進行初始化,則可能會很痛苦。 但是,如果您有很多構造函數參數,則看起來會很混亂,尤其是在沒有關鍵字參數的語言中。 如果您有多種方法來構造有效的對象,則可能很難通過構造函數來顯示它,因為構造函數只能在參數的數量和類型上有所不同。 如果您具有簡單的參數(例如字符串),構造函數也會受到影響。 使用 setter 注入,您可以為每個 setter 命名,以指示該字符串應該執行的操作。 對于構造函數,您只是依靠位置,這很難遵循。 我的偏好是從構造函數注入開始,但是一旦我上面概述的問題開??始成為問題,就可以準備切換到 setter 注入。 #### 7.5. 什么是 Bean 工廠? `BeanFactory`就像一個工廠類,其中包含一系列 bean。`BeanFactory`在其內部保存多個 Bean 的 Bean 定義,然后在每次客戶端請求時實例化 Bean。 `BeanFactory`能夠在實例化協作對象之間創建關聯。 這消除了 bean 本身和 bean 客戶端的配置負擔。`BeanFactory`也參與了 bean 的生命周期,從而調用了自定義的初始化和銷毀??方法。 #### 7.6. 什么是應用程序上下文? Bean 工廠適合簡單的應用程序,但是要利用 Spring 框架的全部功能,您可能需要升級到 Springs 更高級的容器即應用程序上下文。 從表面上看,應用程序上下文與 Bean 工廠相同,兩者都加載 Bean 定義,將 Bean 綁定在一起并根據請求分配 Bean。 但它也提供: * 解決文本消息的方法,包括對國際化的支持。 * 加載文件資源的通用方法。 * 注冊為監聽器的 bean 的事件。 #### 7.7. 應用程序上下文的常見實現是什么? `ApplicationContext`的三種常用實現是: 1. `ClassPathXmlApplicationContext`:它從位于類路徑中的 XML 文件中加載上下文定義,將上下文定義視為類路徑資源。 使用代碼從應用程序的類路徑中加載應用程序上下文。 ```java ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); ``` 2. `FileSystemXmlApplicationContext`:它從文件系統中的 XML 文件加載上下文定義。 使用代碼從文件系統中加載應用程序上下文。 ```java ApplicationContext context = new FileSystemXmlApplicationContext("bean.xml"); ``` 3. `XmlWebApplicationContext`:它從 Web 應用程序中包含的 XML 文件中加載上下文定義。 #### 7.8. 最好使用`BeanFactory`或`ApplicationContext`? `BeanFactory`幾乎只是實例化和配置 bean。 `ApplicationContext`也這樣做,它提供了支持基礎結構,以支持許多企業特定的功能,例如事務和 AOP。 簡而言之,贊成使用`ApplicationContext`。 在本教程中,我們了解了 Spring 中 ioc 和 di 之間的**區別**。 學習愉快!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看