您好,登錄后才能下訂單哦!
這篇文章主要介紹“如何理解Java Spring控制反轉容器”,在日常操作中,相信很多人在如何理解Java Spring控制反轉容器問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何理解Java Spring控制反轉容器”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
什么是容器?
無侵入容器
IOC控制反轉
IOC理論推導
傳統應用程序開發的弊端
“注入”機制
小結
IOC本質
DI(依賴注入)
總結
IoC 容器是 Spring 的核心,也可以稱為 Spring 容器。Spring 通過 IoC 容器來管理對象的實例化和初始化,以及對象從創建到銷毀的整個生命周期。
Spring 中使用的對象都由 IoC 容器管理,不需要我們手動使用 new 運算符創建對象。由 IoC 容器管理的對象稱為 Spring Bean,Spring Bean 就是 Java 對象,和使用 new 運算符創建的對象沒有區別。
Spring 通過讀取 XML 或 Java 注解中的信息來獲取哪些對象需要實例化。
Spring 提供 2 種不同類型的 IoC 容器,即 BeanFactory 和 ApplicationContext 容器。
容器是一種為某種特定組件的運行提供必要支持的一個軟件環境。例如,Tomcat就是一個Servlet容器,它可以為Servlet的運行提供運行環境。類似Docker這樣的軟件也是一個容器,它提供了必要的Linux環境以便運行一個特定的Linux進程。
通常來說,使用容器運行組件,除了提供一個組件運行環境之外,容器還提供了許多底層服務。例如,Servlet容器底層實現了TCP連接,解析HTTP協議等非常復雜的服務,如果沒有容器來提供這些服務,我們就無法編寫像Servlet這樣代碼簡單,功能強大的組件。早期的JavaEE服務器提供的EJB容器最重要的功能就是通過聲明式事務服務,使得EJB組件的開發人員不必自己編寫冗長的事務處理代碼,所以極大地簡化了事務處理。
在設計上,Spring的IoC容器是一個高度可擴展的無侵入容器。所謂無侵入,是指應用程序的組件無需實現Spring的特定接口,或者說,組件根本不知道自己在Spring的容器中運行。這種無侵入的設計有以下好處:
1.應用程序組件既可以在Spring的IoC容器中運行,也可以自己編寫代碼自行組裝配置;
2.測試的時候并不依賴Spring容器,可單獨進行測試,大大提高了開發效率。
Spring提供的容器又稱為IoC容器,什么是IoC?
Ioc—Inversion of Control,即“控制反轉”,不是什么技術,是一個概念,是一種思想。指將傳統上由程序代 碼直接操控的對象調用權交給容器,通過容器來實現對象的裝配和管理。控制反轉就是對對象控制權的轉移,從程序代碼本身反轉到了外部容器。通過容器實現對象的裝配和管理。通俗點講,將對象的創建權交給spring,我們需要new對象,則由spring幫我們創建,然后供我們使用。
那么必然的我們需要創建一個容器,同時需要一種描述來讓容器知道需要創建的對象與對象的關系。這個描述最具體表現就是我們可配置的文件。IoC的實質是如何管理對象,傳統意義上我們使用new方式來創建對象,但在企業應用開發的過程中,大量的對象創建都在程序中維護很容易造成資源浪費,并且不利于程序的擴展。
其實現方式多種多樣。當前比較流行的實現方式是依賴 注入。應用廣泛。
依賴:classA 類中含有 classB 的實例,在 classA 中調用 classB 的方法完成功能,即 classA 對 classB 有依賴。
在理解IoC之前,我們先看看通常的Java組件是如何協作的。
我們先用我們原來的方式寫一段代碼 .
1、先寫一個UserDao接口
2、再去寫Dao的實現類
public class UserDaoOneImpl implements UserDao { @Override public void getUser() { System.out.println("One獲取用戶數據"); } }
3、然后去寫UserService的接口
4、最后寫Service的實現類
5、測試一下
6、再回到UserDao接口
把Userdao的實現類增加一個 .
public class UserDaoMyTwoImpl implements UserDao { @Override public void getUser() { System.out.println("Two獲取用戶數據"); } }
7、我們就需要去service實現類里面修改對應的實現
public class UserServiceImpl implements UserService { private UserDao userDao = new UserDaoTwo(); @Override public void getUser() { userDao.getUser(); } }
在假設, 我們再增加一個Userdao的實現類 .
public class UserDaoThreeImpl implements UserDao { @Override public void getUser() { System.out.println("Three獲取用戶數據"); } }
那么我們要使用Three , 又需要去service實現類里面修改對應的實現 . 假設我們的這種需求非常大 , 這種方式就根本不適用了, 甚至反人類對吧 , 每次變動 , 都需要修改大量代碼 . 這種設計的耦合性太高了, 牽一發而動全身 .
注入應用程序某個對象,應用程序依賴的對象
依賴注入可以通過set()方法實現。但依賴注入也可以通過構造方法實現。Spring的IoC容器同時支持屬性注入和構造方法注入,并允許混合使用。
我們可以在需要用到他的地方 , 不去實現它 , 而是留出一個接口 , 利用set , 我們去代碼里修改下 .
@Test public void test(){ UserServiceImpl service = new UserServiceImpl(); service.setUserDao( new UserDaoTwoImpl() ); service.getUser(); //那我們現在又想添加Three去實現呢 service.setUserDao( new UserDaoThreeImpl() ); service.getUser(); }
以前所有東西都是由程序去進行控制創建 , 而現在是由我們自行控制創建對象 , 把主動權交給了調用者 . 程序不用去管怎么創建,怎么實現了 . 它只負責提供一個接口 .
這種思想 , 從本質上解決了問題 , 我們程序員不再去管理對象的創建了 , 更多的去關注業務的實現 . 耦合性大大降低 . 這也就是IOC的原型 !
傳統程序設計如圖,都是主動去創建相關對象然后再組合起來:
沒有什么是加一層解決不了的
當有了IoC/DI的容器后,在客戶端類中不再主動去創建這些對象了
IoC是Spring框架的核心內容,使用多種方式完美的實現了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置實現IoC。
Spring容器在初始化時先讀取配置文件,根據配置文件或元數據創建與組織對象存入容器中,程序使用時再從Ioc容器中取出需要的對象。
控制反轉是一種通過描述(XML或注解)并通過第三方去生產或獲取特定對象的方式。在Spring中實現控制反轉的是IoC容器,其實現方法是依賴注入(Dependency Injection,DI)。
IoC的一個重點是在系統運行中,動態的向某個對象提供它所需要的其他對象。這一點是通過DI(Dependency Injection,依賴注入)來實現的。 比如對象A需要操作數據庫,以前我們總是要在A中自己編寫代碼來獲得一個Connection對象,有了 spring我們就只需要告訴spring,A中需要一個Connection,至于這個Connection怎么構造,何時構造,A不需要知道。在系統運行時,spring會在適當的時候制造一個Connection,然后像打針一樣,注射到A當中,這樣就完成了對各個對象之間關系的控制。A需要依賴 Connection才能正常運行,而這個Connection是由spring注入到A中的,依賴注入的名字就這么來的。那么DI是如何實現的呢? Java 1.3之后一個重要特征是反射(reflection),它允許程序在運行的時候動態的生成對象、執行對象的方法、改變對象的屬性,spring就是通過反射來實現注入的。
到此,關于“如何理解Java Spring控制反轉容器”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。