1. 程式人生 > >Spring IOC和AOP 原理徹底搞懂

Spring IOC和AOP 原理徹底搞懂

Spring提供了很多輕量級應用開發實踐的工具集合,這些工具集以介面、抽象類、或工具類的形式存在於Spring中。通過使用這些工具集,可以實現應用程式與各種開源技術及框架間的友好整合。比如有關jdbc封裝的資料訪問工具Spring JDBC,有關編寫單元測試的spring test包以及spring-mock,有關訪問動態指令碼語言的Spring Script,另外還有傳送郵件的工具Spring Mail、日程及任務處理工具Spring scheduling等。 可以這麼說,大多數企業級應用開發中經常涉及到的一些通用的問題,都可以通過Spring提供的一些實用工具包輕鬆解決

依賴注入的三種方式:(1)介面注入(2)Construct注入(3)Setter注入

控制反轉(IoC)與依賴注入(DI)是同一個概念,引入IOC的目的:(1)脫開、降低類之間的耦合;(2)倡導面向介面程式設計、實施依賴倒換原則; (3)提高系統可插入、可測試、可修改等特性。
具體做法:(1)將bean之間的依賴關係儘可能地抓換為關聯關係;
(2)將對具體類的關聯儘可能地轉換為對Java interface的關聯,而不是與具體的服務物件相關聯;
(3)Bean例項具體關聯相關Java interface的哪個實現類的例項,在配置資訊的元資料中描述;
(4)由IoC元件(或稱容器)根據配置資訊,例項化具體bean類、將bean之間的依賴關係注入進來。

org.springframework.beans及org.springframework.context包是Spring IoC容器的基礎。BeanFactory

提供的高階配置機制,使得管理任何性質的物件成為可能。ApplicationContext是BeanFactory的擴充套件,功能得到了進一步增強,比如更易與Spring AOP整合、訊息資源處理(國際化處理)、事件傳遞及各種不同應用層的context實現(如針對web應用的WebApplicationContext)。 簡而言之,BeanFactory提供了配製框架及基本功能,而ApplicationContext則增加了更多支援企業核心內容的功能。ApplicationContext完全由BeanFactory擴充套件而來,因而BeanFactory所具備的能力和行為也適用於ApplicationContext。

IoC容器負責容納bean,並對bean進行管理。在Spring中,BeanFactory是IoC容器的核心介面。它的職責包括:例項化、定位、配置應用程式中的物件及建立這些物件間的依賴。Spring為我們提供了許多易用的BeanFactory實現,XmlBeanFactory就是最常用的一個。該實現將以XML方式描述組成應用的物件以及物件間的依賴關係。XmlBeanFactory類將持有此XML配置元資料,並用它來構建一個完全可配置的系統或應用。

實現化容器:

  1. Resource resource = new FileSystemResource("beans.xml");  
  2. BeanFactory factory = new XmlBeanFactory(resource);  
  3. ... 或...  
  4. ClassPathResource resource = new ClassPathResource("beans.xml");  
  5. BeanFactory factory = new XmlBeanFactory(resource);  
  6. ... 或...  
  7. ApplicationContext context = new ClassPathXmlApplicationContext(  
  8.         new String[] {"applicationContext.xml""applicationContext-part2.xml"});  
  9. // of course, an ApplicationContext is just a BeanFactory
  10. BeanFactory factory = (BeanFactory) context;  
將XML配置檔案分拆成多個部分是非常有用的。為了載入多個XML檔案生成一個ApplicationContext例項,可以將檔案路徑作為字串陣列傳給ApplicationContext構造器。而bean factory將通過呼叫bean defintion reader從多個檔案中讀取bean定義。 通常情況下,Spring團隊傾向於上述做法,因為這樣各個配置並不會查覺到它們與其他配置檔案的組合。另外一種方法是使用一個或多個的<import/>元素來從另外一個或多個檔案載入bean定義。所有的<import/>元素必須放在<bean/>元素之前以完成bean定義的匯入。 讓我們看個例子:
<beans><import resource="services.xml"/>
    <import resource="resources/messageSource.xml"/>
    <import resource="/resources/themeSource.xml"/>
      <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>
  </beans>
在上面的例子中,我們從3個外部檔案:services.xmlmessageSource.xmlthemeSource.xml來載入bean定義。這裡採用的都是相對路徑,因此,此例中的services.xml一定要與匯入檔案放在同一目錄或類路徑,而messageSource.xmlthemeSource.xml的檔案位置必須放在匯入檔案所在目錄下的resources目錄中。正如你所看到的那樣,開頭的斜槓‘/’實際上可忽略。因此不用斜槓‘/’可能會更好一點。 根據Spring XML配置檔案的Schema(或DTD),被匯入檔案必須是完全有效的XML bean定義檔案,且根節點必須為<beans/> 元素。 BeanFactory和FactoryBean的區別,簡而言之,BeanFactory是載入的容器,載入一切的BEAN,而FactoryBean用於建立代理類
===============================================================上面已講到  BeanFactory它的職責包括:例項化、定位、配置應用程式中的物件及建立這些物件間的依賴 FactoryBean(通常情況下,bean無須自己實現工廠模式,Spring容器擔任工廠角色;但少數情況下,容器中的bean本身就是工廠,其作用是產生其它bean例項),作用是產生其他bean例項。通常情況下,這種bean沒有什麼特別的要求,僅需要提供一個工廠方法,該方法用來返回其他bean例項。由工廠bean產生的其他bean例項,不再由Spring容器產生,因此與普通bean的配置不同,不再需要提供class元素。 ProxyFactoryBean用於建立代理(根據Advisor生成的Bean,也就是TargetBean的代理) 我們的Advisor,PointCut等等,其最終目的都是為了建立這個代理。 ===============================================================下面將講到

AOP全名Aspect-Oriented Programming,中文直譯為面向切面(方面)程式設計,當前已經成為一種比較成熟的程式設計思想,可以用來很好的解決應用系統中分佈於各個模組的交叉關注點問題。在輕量級的J2EE中應用開發中,使用AOP來靈活處理一些具有橫切性質的系統級服務,如事務處理、安全檢查、快取、物件池管理等,已經成為一種非常適用的解決方案。 AOP中比較重要的概念有:Aspect、JoinPoint、PonitCut、Advice、Introduction、Weave、Target Object、Proxy Object等

引介(Introduction)是指給一個現有類新增方法或欄位屬性,引介還可以在不改變現有類程式碼的情況下,讓現有的Java類實現新的介面,或者為其指定一個父類從而實現多重繼承。相對於增強(Advice)可以動態改變程式的功能或流程來說,引介(Introduction)則用來改變一個類的靜態結構。比如我們可以讓一個現有為實現java.lang.Cloneable介面,從而可以通過clone()方法複製這個類的例項。

攔截器是用來實現對連線點進行攔截,從而在連線點前或後加入自定義的切面模組功能。在大多數JAVA的AOP框架實現中,都是使用攔截器來實現欄位訪問及方法呼叫的攔截(interception)。所用作用於同一個連線點的多個攔截器組成一個聯結器鏈(interceptor chain),連結上的每個攔截器通常會呼叫下一個攔截器。Spring AOP及JBoos AOP實現都是採用攔截器來實現的。

面向物件程式設計(OOP)解決問題的重點在於對具體領域模型的抽象,而面向切面程式設計(AOP)解決問題的關鍵則在於對關注點的抽象。也就是說,系統中對於一些需要分散在多個不相關的模組中解決的共同問題,則交由AOP來解決;AOP能夠使用一種更好的方式來解決OOP不能很好解決的橫切關注點問題以及相關的設計難題來實現鬆散耦合。因此,面向方面程式設計 (AOP) 提供另外一種關於程式結構的思維完善了OOP,是OOP的一種擴充套件技術,彌補補了OOP的不足。

AOP概念詳解:注意以下例項<aop:開頭的AspectJ的概念,Spring沒有分的這麼細。

  — 方面(Aspect):一個關注點的模組化,這個關注點實現可能另外橫切多個物件。事務管理是一個很好的橫切關注點例子。方面用Spring的Advisor或攔截器實現, 然後可以通過@Aspect標註或在applictionContext.xml中進行配置:

      <aop:aspect id="fourAdviceAspect" ref="fourAdviceBean" order="2"

  — 連線點(Joinpoint):程式執行過程中的行為,如方法的呼叫或特定的異常被丟擲,在程式碼上有JoinPoint類和ProceedingJoinPoint類,如下所示,可以通過JoinPoint獲取很多引數,JoinPoint一般用在Advice實現方法中作為引數傳入,ProceedingJoinPoint用於實現圍繞Advice的引數傳入。  通過下面JoinPoint的介面可以看出通過JoinPoint可以得到代理物件和Target物件。

  1. package org.aspectj.lang;  
  2. import org.aspectj.lang.reflect.SourceLocation;  
  3. publicinterface JoinPoint {  
  4.     String toString();         //連線點所在位置的相關資訊
  5.     String toShortString();     //連線點所在位置的簡短相關資訊
  6.     String toLongString();     //連線點所在位置的全部相關資訊
  7.     Object getThis();         //返回AOP代理物件
  8.     Object getTarget();       //返回目標物件
  9.     Object[] getArgs();       //返回被通知方法引數列表
  10.     Signature getSignature();  //返回當前連線點簽名
  11.     SourceLocation getSourceLocation();//返回連線點方法所在類檔案中的位置
  12.     String getKind();        //連線點型別
  13.     StaticPart getStaticPart(); //返回連線點靜態部分
  14. }  
  15. publicinterface ProceedingJoinPoint extends JoinPoint {  
  16.     public Object proceed() throws Throwable;  
  17.     public Object proceed(Object[] args) throws Throwable;  
  18. }  

      — 切入點(Pointcut):指定一個Adivce將被引發的一系列連線點的集合。AOP框架必須允許開發者指定切入點,例如,使用正則表示式。

          xml中配置:

<aop:pointcut id="myPointcut" expression="execution(* com.wicresoft.app.service.impl.*.*(..))" method="release" /> 

          或使用Annoation :@pointcut("execution * transfer(..)")並用一個返回值為void,方法體為空的方法來命名切入點如:  privatevoid anyOldTransfer(){}

     之後就可以在Advice中引用,如: @AfterReturning(pointcut="anyOldTransfer()", returning="reVal")  

  1. package org.springframework.aop;  
  2. publicinterface Pointcut {  
  3.     ClassFilter getClassFilter();  
  4.     MethodMatcher getMethodMatcher();  
  5.     Pointcut TRUE = TruePointcut.INSTANCE;  
  6. }  
  7. package org.springframework.aop;  
  8. publicinterface ClassFilter {  
  9.      boolean matches(Class<?> clazz);//如果clazz與我們關注的現象相符時返回true,負責返回false
  10.      ClassFilter TRUE = TrueClassFilter.INSTANCE;//靜態引數 如果型別對於要撲捉的Pointcut來說無所謂,可將此引數傳遞給Pointcut
  11. }  
  12. package org.springframework.aop;  
  13. publicinterface MethodMatcher {  
  14.    boolean matches(Method method, Class<?> targetClass);  
  15.  /** 
  16.   * 是否對引數值敏感 
  17.   * 如果為false表明匹配時不需要判斷引數值(引數值不敏感),稱之為StaticMethodMatcher,這時只有 
  18.   * matches(Method method, Class<?> targetClass); 被執行,執行結果可以快取已提高效率。 
  19.   * 如果為true表明匹配時需要判斷引數值(引數值敏感),稱之為DynamicMethodMatcher,這時先執行 
  20.   * matches(Method method, Class<?> targetClass);如果返回true,然後再執行 
  21.   * boolean matches(Method method, Class<?> targetClass, Object[] args);已做進一步判斷 
  22.   *  
  23.   */
  24.  boolean isRuntime();  
  25.  boolean matches(Method method, Class<?> targetClass, Object[] args);  
  26.  MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;  
  27. }  

關於PointCut中使用的execution的說明:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?) 

modifiers-pattern:方法的操作許可權

ret-type-pattern:返回值

declaring-type-pattern:方法所在的包

name-pattern:方法名

parm-pattern:引數名

throws-pattern:異常

記憶法則就是Java定義一個方法時的樣子:public boolean produceValue(int oo) throws Exception, 只要在方法名前加上包名就可以了。

其中,除ret-type-pattern和name-pattern之外,其他都是可選的。上例中,execution(* com.spring.service.*.*(..))表示com.spring.service包下,返回值為任意型別;方法名任意;引數不作限制的所有方法。

常見的PointCut結構圖:


  — 通知(Advice):在特定的連線點,AOP框架執行的動作。各種型別的通知包括“around”、“before”和“throws”通知。通知型別將在下面討論。許多AOP框架包括Spring都是以攔截器做通知模型,維護一個“圍繞”連線點的攔截器鏈。Advice中必須用到PointCut

     在xml中配置,配置中的method為Aspect實現類中的方法名,使用pointcut自定義或pointcut-ref進行引用已有pointcut

       <aop:before pointcut="execution(* com.wicresoft.app.service.impl.*.*(..))" method="authority" /> 

       <aop:after pointcut="execution(* com.wicresoft.app.service.impl.*.*(..))" method="release" /> 

       <aop:after-returning pointcut="execution(* com.wicresoft.app.service.impl.*.*(..))" method="log" />

       <aop:around pointcut="execution(* com.wicresoft.app.service.impl.*.*(..))" method="processTx" /> 

       <aop:after-throwing pointcut-ref="myPointcut" method="doRecovertyActions" throwing="ex" />     

或使用Annoation: 

       @Before("execution(* com.wicresoft.app.service.impl.*.*(..))")

@AfterReturning(returning="rvt", pointcut="execution(* com.wicresoft.app.service.impl.*.*(..))")

@AfterThrowing(throwing="ex", pointcut="execution(* com.wicresoft.app.service.impl.*.*(..))")

       @After("execution(* com.wicresoft.app.service.impl.*.*(..))")

 @Around

相關推薦

Spring IOCAOP 原理徹底

Spring提供了很多輕量級應用開發實踐的工具集合,這些工具集以介面、抽象類、或工具類的形式存在於Spring中。通過使用這些工具集,可以實現應用程式與各種開源技術及框架間的友好整合。比如有關jdbc封裝的資料訪問工具Spring JDBC,有關編寫單元測試的

spring iocaop原理理解

ioc的意思是控制反轉,表示建立物件並不是new出來的,而是通過spring配置建立的,實現原理是xml配置檔案+SAX解析+工廠模式。aop的意思是面向切面程式設計,表示將封裝好的物件剖開,找出對多個物件產生影響的公共行為,並封裝成可重用的模組,這種被成為“切面”,切面將那

關於spring IOCAOP的解析原理舉例

1.關於spring ioc   這段時間也著實好好的看了下spring的相關書籍,對其也有了大概和初步的認識和理解,雖然之前也一直聽說spring是一個非常優秀的開源框架,可一直沒有機會學習和使用(是不是有點落伍了?呵呵),所以呢,這段時間就重點學習了spring(一個星期的時間

springIOCAOP原理分析

 先從IOC說起,這個概念其實是從我們平常new一個物件的對立面來說的,我們平常使用物件的時候,一般都是直接使用關鍵字類new一個物件,那這樣有什麼壞處呢?其實很顯然的,使用new那麼就表示當前模組已經不知不覺的和new的物件耦合了,而我們通常都是更高層次的抽象模組呼叫

關於spring,IOCAOP的解析原理舉例

先從IOC說起,這個概念其實是從我們平常new一個物件的對立面來說的,我們平常使用物件的時候,一般都是直接使用關鍵字類new一個物件,那這樣有什麼壞處呢?其實很顯然的,使用new那麼就表示當前模組已經不知不覺的和new的物件耦合了,而我們通常都是更高層次的抽象模組

Spring IoCAOP使用擴展

處理類型 can 初始 ext @aspectj 環繞增強 組件 ont qualifier   Spring提供了設值註入,構造註入等依賴註入方式。   使用p命令空間可以簡化屬性註入的配置。   Spring提供的增強處理類型包括前置增強,異常拋出增強,環繞增強,最終增

Spring IoCAOP使用擴展(二)

cor ima 容器 常用 size ops ali class sta 一、IOC的實現方式:   Set註入:熟悉必須有公共set方法;   構造器註入:可以根據構造器參數名稱、下標註入;   p命名空間註入:要求有set方法;            內部bean的實現

Spring IOC AOP

文件 編程思想 dep nbsp 織入 擴展 con 集中管理 重復 一.  IOC   1. 概念及原理   IOC: Inversion of Control(控制反轉)是一種設計思想,就是容器控制應用程序所需要的外部資源的創建和管理,然後將其反轉給應用程序.對象及其依

Spring IocAOP的理解

轉載自:https://blog.csdn.net/u013148153/article/details/80293587  Ioc和AOP是Spring的兩大核心,面試的時候也經常被問及對這兩個概念的理解,因此也記下我對此的理解,方便以後查漏補缺。  一、控制反轉(Ioc,

Spring IOCAOP

Spring提供了很多輕量級應用開發實踐的工具集合,這些工具集以介面、抽象類、或工具類的形式存在於Spring中。通過使用這些工具集,可以實現應用程式與各種開源技術及框架間的友好整合。比如有關jdbc封裝的資料訪問工具Spring JDBC,有關編寫單元測試的spring t

自己動手實現的 Spring IOC AOP - 上篇

1. 背景 我在大四實習的時候開始接觸 J2EE 方面的開發工作,也是在同時期接觸並學習 Spring 框架,到現在也有快有兩年的時間了。不過之前沒有仿寫過 Spring IOC 和 AOP,只是巨集觀上對 Spring IOC 和 AOP 原理有一定的認識。所以為了更進一步理解 Spring

Spring——IoCAop使用拓展

一、多種方式實現依賴注入 構造注入 設值注入 p名稱空間注入 1、構造注入:通過建構函式注入資料。 構造注入的優劣勢:構造注入的時效性好,在物件例項化時就得到所依賴的物件,便於在物件的初始化時就得到所依賴的物件,便於在物件的初始化方法中使用依賴物件;但受限於方法

Spring IOCSpring AOP的實現原理(原始碼主線流程)

寫在前面      正本文參考了《spring技術內幕》和spring 4.0.5原始碼。本文只描述原理流程的主線部分,其他比如驗證,快取什麼可以具體參考原始碼理解。Spring IOC一、容器初始化      容器的初始化首先是在對應的構造器中進行,在application

看完讓你徹底Websocket原理

找到 說了 成了 原理 兩層 cep 告訴 edi 純粹 偶然在知乎上看到一篇回帖,瞬間覺得之前看的那麽多資料都不及這一篇回帖讓我對 websocket 的認識深刻有木有。所以轉到我博客裏,分享一下。比較喜歡看這種博客,讀起來很輕松,不枯燥,沒有布道師的陣仗,純粹為分享。廢

徹底反斜杠“”正斜杠"/"的區別

影響 使用 web應用 圖片 命令 mic ont http () 正斜杠,符號是"/";反斜杠,符號是"\"。 在知乎中看到一個答案如下: 知乎用戶:“在絕大多數地方,用的都是/(slash),包括Mac/Linux,也包括URL。你唯一需要記住的是,Microsoft這

理解Spring中的IOCAOP

nfa 重復 高度 只需要 spring框架 aop 編程 靈活 攔截 我們是在使用Spring框架的過程中,其實就是為了使用IOC,依賴註入和AOP,面向切面編程,這兩個是Spring的靈魂。 主要用到的設計模式有工廠模式和代理模式 IOC就是典型的工廠模式,通過se

用通俗的語言解釋 Spring 中的 DI 、IOC AOP概念

private rgs 完成 編程 而是 無需 解決 情況 分離關註點 DI 所謂依賴,從程序的角度看,就是比如A要調用B的方法,那麽A就依賴於B,反正A要用到B,則A依賴於B。所謂倒置,你必須理解如果不倒置,會怎麽著,因為A必須要有B,才可以調用B,如果不倒置,意思就是A

深入理解Spring的兩大特征(IOCAOP)<轉>

編譯器 如果 定義 包括 其他 enc row 這就是 生命 在某博主的博客上看到一篇解釋Spring的兩大核心IOC與AOP的文章,借此轉發一下,希望能夠幫助到更多的人。 原文地址:https://blog.csdn.net/gloomy_114/article/deta

【Java】 Spring 框架初步學習總結(一)簡單實現 IoC AOP

1.0 其中 表示 只需要 第一篇 否則 info fin pojo   Spring 是一個開源的設計層面的輕量級框架,Spring 的好處網上有太多,這裏就不在贅述。   IoC 控制反轉和 AOP 面向切面編程是 Spring 的兩個重要特性。   IoC(Inver

轉--看完讓你徹底Websocket原理

接下來 lur 耗資源 最終 ive img pro -- 傳遞 偶然在知乎上看到一篇回帖,瞬間覺得之前看的那麽多資料都不及這一篇回帖讓我對 websocket 的認識深刻有木有。所以轉到我博客裏,分享一下。比較喜歡看這種博客,讀起來很輕松,不枯燥,沒有布道師的陣仗,純粹為