談談Spring中的IOC、DI和AOP概念

看了大神的解釋感覺受益匪淺,所以就將其保存,方便自己看,並最後總結出自己的理解


1. IOC(Inverse of Control):控制反轉,也可以稱爲依賴倒置。

        所謂依賴,從程序的角度看,就是比如A要調用B的方法,那麼A就依賴於B,反正A要用到B,則A依賴於B。所謂倒置,你必須理解如果不倒置,會怎麼着,因爲A必須要有B,纔可以調用B,如果不倒置,意思就是A主動獲取B的實例:B b = new B(),這就是最簡單的獲取B實例的方法(當然還有各種設計模式可以幫助你去獲得B的實例,比如工廠、Locator等等),然後你就可以調用b對象了。所以,不倒置,意味着A要主動獲取B,才能使用B;到了這裏,就應該明白了倒置的意思了。倒置就是A要調用B的話,A並不需要主動獲取B,而是由其它人自動將B送上門來。
        形象的舉例就是:
        通常情況下,假如你有一天在家裏口渴了,要喝水,那麼你可以到你小區的小賣部去,告訴他們,你需要一瓶水,然後小賣部給你一瓶水!這本來沒有太大問題,關鍵是如果小賣部很遠,那麼你必須知道:從你家如何到小賣部;小賣部裏是否有你需要的水;你還要考慮是否開着車去;等等等等,也許有太多的問題要考慮了。也就是說,爲了一瓶水,你還可能需要依賴於車等等這些交通工具或別的工具,問題是不是變得複雜了?那麼如何解決這個問題呢?
        解決這個問題的方法很簡單:小賣部提供送貨上門服務,凡是小賣部的會員,你只要告知小賣部你需要什麼,小賣部將主動把貨物給你送上門來!這樣一來,你只需要做兩件事情,你就可以活得更加輕鬆自在:
        第一:向小賣部註冊爲會員。
        第二:告訴小賣部你需要什麼。

        這和Spring的做法很類似!Spring就是小賣部,你就是A對象,水就是B對象
        第一:在Spring中聲明一個類:A
        第二:告訴Spring,A需要B

        假設A是UserAction類,而B是UserService類

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <bean id="userService" class="org.leadfar.service.UserService"/>  
  2. <bean id="documentService" class="org.leadfar.service.DocumentService"/>  
  3. <bean id="orgService" class="org.leadfar.service.OrgService"/>  
  4.   
  5. <bean id="userAction" class="org.leadfar.web.UserAction">  
  6.      <property name="userService" ref="userService"/>  
  7. </bean>  

        在Spring這個商店(工廠)中,有很多對象/服務:userService,documentService,orgService,也有很多會員:userAction等等,聲明userAction需要userService即可,Spring將通過你給它提供的通道主動把userService送上門來,因此UserAction的代碼示例類似如下所示:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package org.leadfar.web;  
  2. public class UserAction{  
  3.      private UserService userService;  
  4.      public String login(){  
  5.           userService.valifyUser(xxx);  
  6.      }  
  7.      public void setUserService(UserService userService){  
  8.           this.userService = userService;  
  9.      }  
  10. }  

        在這段代碼裏面,你無需自己創建UserService對象(Spring作爲背後無形的手,把UserService對象通過你定義的setUserService()方法把它主動送給了你,這就叫依賴注入!),當然咯,我們也可以使用註解來注入。Spring依賴注入的實現技術是:動態代理

2. AOP:即面向切面編程

        面向切面編程的目標就是分離關注點。什麼是關注點呢?就是你要做的事,就是關注點。假如你是個公子哥,沒啥人生目標,天天就是衣來伸手,飯來張口,整天只知道玩一件事!那麼,每天你一睜眼,就光想着吃完飯就去玩(你必須要做的事),但是在玩之前,你還需要穿衣服、穿鞋子、疊好被子、做飯等等等等事情,這些事情就是你的關注點,但是你只想吃飯然後玩,那麼怎麼辦呢?這些事情通通交給別人去幹。在你走到飯桌之前,有一個專門的僕人A幫你穿衣服,僕人B幫你穿鞋子,僕人C幫你疊好被子,僕人C幫你做飯,然後你就開始吃飯、去玩(這就是你一天的正事),你幹完你的正事之後,回來,然後一系列僕人又開始幫你幹這個幹那個,然後一天就結束了!

        AOP的好處就是你只需要幹你的正事,其它事情別人幫你幹。也許有一天,你想裸奔,不想穿衣服,那麼你把僕人A解僱就是了!也許有一天,出門之前你還想帶點錢,那麼你再僱一個僕人D專門幫你幹取錢的活!這就是AOP。每個人各司其職,靈活組合,達到一種可配置的、可插拔的程序結構。

        從Spring的角度看,AOP最大的用途就在於提供了事務管理的能力。事務管理就是一個關注點,你的正事就是去訪問數據庫,而你不想管事務(太煩),所以,Spring在你訪問數據庫之前,自動幫你開啓事務,當你訪問數據庫結束之後,自動幫你提交/回滾事務!




3.IOC是一種叫做“控制反轉”的設計思想和DI的使用場景。

1)、較淺的層次——從名字上解析 
“控制”就是指對 對象的創建、維護、銷燬等生命週期的控制,這個過程一般是由我們的程序去主動控制的,如使用new關鍵字去創建一個對象(創建),在使用過程中保持引用(維護),在失去全部引用後由GC去回收對象(銷燬)。 
“反轉”就是指對 對象的創建、維護、銷燬等生命週期的控制由程序控制改爲由IOC容器控制,需要某個對象時就直接通過名字去IOC容器中獲取。

2)、更深的層次——提到DI,依賴注入,是IOC的一種重要實現 
一個對象的創建往往會涉及到其他對象的創建,比如一個對象A的成員變量持有着另一個對象B的引用,這就是依賴,A依賴於B。IOC機制既然負責了對象的創建,那麼這個依賴關係也就必須由IOC容器負責起來。負責的方式就是DI——依賴注入,通過將依賴關係寫入配置文件,然後在創建有依賴關係的對象時,由IOC容器注入依賴的對象,如在創建A時,檢查到有依賴關係,IOC容器就把A依賴的對象B創建後注入到A中(組裝,通過反射機制實現),然後把A返回給對象請求者,完成工作。

3)、IOC的意義何在? 
IOC並沒有實現更多的功能,但它的存在使我們不需要很多代碼、不需要考慮對象間複雜的耦合關係就能從IOC容器中獲取合適的對象,而且提供了對 對象的可靠的管理,極大地降低了開發的複雜性。


最後個人總結:

IOC(控制反轉):就是將對象生命週期的控制反轉過來,不需要主動的去創建操作,需要時會從IOC容器中取出,減少了開發者繁瑣的創建過程

DI(依賴注入):也就是IOC的真正實現過程,IOC容器就把A依賴的對象B創建後注入到A中(組裝,通過反射機制實現),然後把A返回給對象請求者,完成工作

AOP(面向切面編程):就是開發者直接對關注的重點就行操作,不需要對其他操作就行關注,例如事務管理就是一個關注點,你的正事就是去訪問數據庫,而你不想管事務,所以,Spring在你訪問數據庫之前,自動幫你開啓事務,當你訪問數據庫結束之後,自動幫你提交/回滾事務


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章