對 Spring 的核心(AOP 和 IOC)的理解(大白話)


Spring

  首先它是一個開源而輕量級的框架。其核心容器的主要組件是Bean工廠(BeanFactory)。Bean工廠使用控制反轉(IOC)模式來降低程序代碼之間的耦合度,並提供了面向切面編程(AOP)的實現。

  正如其字面意思,是程序員的春天,大大地降低了體力勞動~

  Spring 常用注解

  1、@Component : 組件。標識這是個受 spring 管理的組件。(當組件不好歸類時使用)

  2、@Controller:用於標注控制層組件(如 struts 中的 action)。

      使用這個注解,且不指定 value 的時候,默認 bean 的名字為類名首字母小寫。

  3、@Service:用於標注業務層組件。

  4、@Repository:用於標注數據訪問組件,即DAO組件。

  5、@Scope("prototype") :將Action的范圍設置為原型(也就是多例的)。保證每一個請求有一個單獨的 Action 來處理,避免 struts 中 Action 的線程問題。

      由於 spring 默認是單例的,這種情況下,只會創建一個 Action 對象,每次訪問都是同一個對象,數據不安全。Struts 要求必須是多例的,每次訪問對應的不同的 Action 對象。這個注解相當於在 spring 中保證了這一點。

      有問題啊:為什么 spring mvc 又是建議單例的呢?它不擔心數據安全嗎?  -- 個人理解:我們表現層使用 struts 時建議是多例的原因是,Struts 是通過模型驅動和屬性驅動來獲取前端頁面參數的,Action 里面存在大量成員變量,單例模式會導致屬性重復使用,數據不安全。而 spring mvc 獲取參數的模式是通過方法形參,一般之作用於方法,故不需要開啟多例。

  6、@Autowired:默認按類型進行自動裝配。在容器查找匹配的Bean,當有且僅有一個匹配的Bean時,Spring將其注入@Autowired標注的變量中。

  7、@Resource:默認按名稱裝配,當找不到與名稱匹配的bean才會按類型裝配。

 

AOP

    -- Aspect-Oriented Programming 面向切面編程

  前言:我們都知道 Java 是 OOP-面向對象編程的,它有自己的優勢,也有自己的不足。比如說:在我們開發中,都會有一條業務主線(即客戶的需求)。而我們要做的就是實現這個主線上的需求。我們在實現這些功能的時候,經常要干一些額外的不可避免的事情,比如事務的管理,日志的記錄等,就很繁雜且代碼量增多。

  所以 Spring 提供了另一種角度來思考程序結構,也就是把這一些事情剝離出來,然后適時適地的把它們加入到我們的代碼中,比如說 聲明式事務管理的時候,我們在 service 層檢測到save*、update*這些方法要被調用的時候,我們先進行開啟事務什么的,這就是AOP,面向編程的思想。

  總的來說,在運行時,動態地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切面的編程。

 

  AOP 名詞的大白話解說

  1、通知  --  Advice

    就是要給目標類織入的事情。就是我們說的額外的一些共同的事情,也就是上面說的 事務,日志等。你給先定義好,然后在想用的地方用一下。

  2、連接點  -- JoinPoint

     就是 spring 允許你使用通知的地方,那可真就多了,基本每個方法的前,后(兩者都有也行),或拋出異常時都可以是連接點,spring 的話只支持方法連接點。和方法有關的前前后后(拋出異常),都是連接點。一個類的所有方法前、后、拋出異常時等都是連接點。

  3、切入點  -- Pointcut

    上面說的連接點的基礎上,來定義切入點,你的一個類里,有15個方法,那就有幾十個連接點了對把,但是你並不想在所有方法附近都使用通知(使用叫織入,下面再說),你只想讓其中的幾個,在調用這幾個方法之前,之后或者拋出異常時干點什么,那么就用切點來定義這幾個方法,讓切點來篩選連接點,選中那幾個你想要的方法。(比如需要開啟事務的只是“ save * ”、“ update * ”..等等這些方法)。切入點就是定義了哪個類里面的哪些方法的會得到通知

  4、切面  -- Aspect

    切面是通知和切入點的結合。現在發現了吧,沒連接點什么事情,連接點就是為了讓你好理解切點,搞出來的,明白這個概念就行了。通知說明了干什么和什么時候干(什么時候通過方法名中的before,after,around等就能知道),而切入點說明了在哪干(指定到底是哪個方法),這就是一個完整的切面定義。

  5、織入  -- weaving

    把切面應用到目標對象來創建新的代理對象的過程。可以在編譯時、類加載時、運行時完成的織入,spring 采用的是 在運行時完成織入

  6、引入  -- introduction

    允許我們向現有的類添加新方法屬性。這不就是把切面(也就是新方法屬性:通知定義的)用到目標類中嗎~

  7、目標  -- target

    引入中所提到的目標類,也就是要被通知的對象也就是真正的業務邏輯,他可以在毫不知情的情況下,被咱們織入切面。而自己專注於業務本身的邏輯。

  8、AOP 的代理  -- AOP Proxy

    目標對象被織入增強后產生的結果類。我的理解它是 spring 為了騙過 jvm 的類型檢查,搞出來的一個偽裝類。

    spring 偽裝采用了兩種方式:

    ① 實現和目標類相同的接口  -- 與目標類為雙胞胎兄弟(要找我哥辦事,弟弟我冒充哥哥收點禮物,再讓我哥給你辦事~)

 

    ② 生成子類調用  -- 給目標類當兒子(學會了爸爸的本事,都找我辦就好了,但是我要先收點禮物~)

 

IOC

    -- Inversion of Control 控制反轉

  創建對象的控制權,被反轉到了 spring 框架。意味着將你設計好的對象交給 spring 控制管理,而不是傳統的在你的對象內部直接控制。

 

  DI  -- Dependency Injection  依賴注入

    由 IOC 容器動態的將某個對象所需要的外部資源(包括對象、資源、常量數據)注入到組件( spring 中的組件如:controller, service..等)之中。

    大白話:也就是 IOC 會把你當前對象所需要的外部資源動態的注入給你。

  IOC 和 DI   -- “被注入對象依賴IOC容器配置依賴對象”。

    大白話:首先控制反轉,我們把對象的控制權交給了 spring 框架的 IOC 容器,所以我們要使用的話,就是依賴 IOC 容器給我們動態注入。

 

  大白話解說IOC(控制反轉)和DI(依賴注入):

  舉個栗子!在 UserAction 中要用到 UserServiceImpl 中的方法,最初的方法是在 UserAction 中通過  UserService userService = new UserServiceImpl; 需要它的時候就 new 出來,控制權在自己手里,但是使用 Spring 后,UserAction 不用主動去創建 UserServiceImpl 的實例了,這個工作已經交給 Spring來做了。然后 你要用的時候再直接問 Spring 要,就可以拿來用了。

  這個時候你就由原來的主動創建,變成了被動依賴 Spring 創建好之后給你的注入,才能使用。控制權已經反轉給 Spring 了~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM