Spring原理與原始碼分析系列(一)- Spring IoC入門
一、Spring簡介
什麼是Spring
• 輕量:Spring是輕量級的,基本的版本大小為2MB
• 控制反轉:Spring通過控制反轉實現了鬆散耦合,物件們給出它們的依賴,而不是建立或查詢依賴的物件們。
• 面向切面的程式設計AOP:Spring支援面向切面的程式設計,並且把應用業務邏輯和系統服務分開。
• 容器:Spring包含並管理應用中物件的生命週期和配置
• MVC框架: Spring-MVC
• 事務管理:Spring提供一個持續的事務管理介面,可以擴充套件到上至本地事務下至全域性事務JTA
• 異常處理:Spring提供方便的API把具體技術相關的異常
Spring框架概述
Spring Framework由約20個模組組成的特徵組成。這些模組分為核心容器,資料訪問/整合,Web,AOP,Instrumentation,Messaging和Test,如下圖所示。
• (1)Core Container
Spring的核心元件有3個:Core,Context和Bean。其中Bean是Spring的主角。在該模組當中,Spring提供了一個IoC容器的實現,用於我們以依賴注入的方式管理物件之間的依賴關係。
• (2)AOP
Spring-AOP:基於代理的AOP支援。
• (3)資料訪問
Spring-JDBC:提供以JDBC訪問資料庫的支援;
Spring-TX:提供程式設計式和宣告式的事務支援;
Spring-ORM:提供對物件/關係對映技術的支援;
Spring-OXM:提供對物件/xml對映技術的支援;
Spring-JMS:提供對JMS的支援。
• (4)Web
Spring-Web:提供基礎的Web整合的功能,在Web專案中提供Spring的容器;
Spring-Webmvc:提供基於Servlet的Spring MVC;
Spring應用場景
Spring發展到現在已經提供了大量的基於Spring的專案,主要有如下專案:
Spring Boot :使用預設開發配置來實現快速開發;
Spring Cloud:為分散式系統開發提供工具集;
Spring Data:對主流的關係型和NoSQL資料庫的支援;
Spring Batch:簡化及優化大量資料的批處理操作;
Spring Security:通過認證和授權保護應用;
Spring AMQP:對基於AMQP的訊息的支援;
Spring Web Flow:基於Spring MVC提供基於嚮導流程式的Web應用開發。
本系列部落格主要總結Spring的IoC、AOP、事務管理、Spring MVC幾個方面的使用以及相關的原始碼分析。
二 、Spring-IoC入門
1 什麼是IoC(依賴注入)
IoC(Inversion of Control),通常被稱為控制反轉,也叫做依賴注入(DI)(當然這種說法是有爭議的,在此不去探究)。
Spring官網也給出了IoC容器的解釋:
何為控制反轉?舉個簡單的例子來說,
在面向物件的系統中,假如在論壇網站中有個評論的介面CommentService,在這個介面中要獲取評論數量,需要通過呼叫CommentDao 中的getCommentCount()方法來獲取。
我們的正常做法是在CommentService中先new CommentDao(),然後再呼叫CommentDao 中相關方法。
程式碼如下:
public class CommentDao { public int getCommentCount(){ return 100; } } public class CommentService { private CommentDao commentDao; public int getCount(){ commentDao = new CommentDao(); return commentDao.getCommentCount(); } public void setCommentDao(CommentDao commentDao) { this.commentDao = commentDao; } }
而IoC的思想即是,在你需要依賴物件的時候,IoC容器即可提供一個已經例項化好的物件給你,這樣你就不需要自己去新建相應的依賴類。
下面將寫一個虛擬碼感受下IoC的過程(不是很嚴謹,感受下過程即可):
(1)首先將CommentDao,宣告為一個Bean(宣告為Bean後,IoC容器即會為其建立一個例項物件);
<bean id = "commenDao" class="com.wgs.spring.demo1.CommentDao"/>
(2)再通過setter依賴注入的方式將CommentDao注入到CommentService當中
<bean id="commentService" class="com.wgs.spring.demo1.CommentService"> <property name="commentDao"> <ref bean="commentDao"></ref> </property> </bean>
(3)當我們在CommentService需要用到CommentDao的時候,直接找IoC容器要到CommentDao的Bean即可。
IoContainer container = new ...; CommentService service = (CommentService)container.getbean("commentService"); int result = service.getCount();
所以,從上述例子可以看出:
通過使用IoC容器,物件依賴關係的管理被反轉了。 即物件之間的相關依賴關係由IoC容器進行管理,並且由IoC完成物件的注入。
在面向物件系統中,物件封裝了資料和對資料的處理,物件的依賴關係常常體現在對資料和方法的依賴上,
而IoC模式是將這些依賴關係通過物件的依賴注入交給框架或IoC容器。
2 依賴注入的3種方式
(1)setter方法注入
上述過程即為setter注入的過程。當前物件只要為其依賴物件所對應的屬性新增setter方法,就可以通過setter方法將相應額依賴物件設定到當前物件中:
public class CommentService { private CommentDao commentDao; public int getCount(){ commentDao = new CommentDao(); return commentDao.getCommentCount(); } public void setCommentDao(CommentDao commentDao) { this.commentDao = commentDao; } }
(2)構造方法注入
即被注入物件可以通過在其構造方法中宣告依賴物件的引數列表,讓IoC容器知道其需要依賴那些物件。
IoC容器會檢查被注入物件的構造方法,取得其需要的依賴物件的引數列表,進而為其注入對應的物件。物件構造完成後就能使用。
public class CommentService { private CommentDao commentDao; public int getCount(){ commentDao = new CommentDao(); return commentDao.getCommentCount(); } public CommentService(CommentDao commentDao){ this.commentDao = commentDao; } }
(3)介面注入
不太常用,在此不介紹。
構造方法注入與setter方法注入對比:
(1)構造方法注入優點是物件在構造完成後即進入就緒狀態,可馬上使用;缺點是當依賴物件較多的時候,構造方法的引數列表會比較長;
(2)setter方法注入允許設定預設值,可以被繼承;
缺點是物件無法在構造完成後就馬上進入就緒狀態。