javascript
【Spring学习】Spring的AOP模块应用详解
面向切面編程(AOP)的思想就是在執行某些代碼前執行另外的代碼,使程序更靈活、擴展性更好,可以隨便地添加刪除某些功能。
javaweb機制中的filter就是面向切面編程的例子。Tomcat會在程序運行的某個時機(即servlet執行前后),執行與servlet、JSP等毫無關系的filter代碼。
AOP把一個業務流程分成幾個部分,例如權限檢查,業務處理,日志記錄,每個部分單獨處理,然后把它們組裝成完整的業務流程。每個部分被稱為切面(Aspect)或者關注點。Spring提供的AOP機制異常靈活,能夠在任何類、任何方法的執行前、后添加攔截器。Spring推薦使用接口編程,Spring提供三種攔截器:方法前攔截器、返回后攔截器、異常拋出攔截器。
下面我們從一個簡單的例子開始學習spring aop:
//Service接口 public interface IAopService{ public void withAop() throws Exception; //將會被攔截 public void withoutAop() throws Exception; //不會被攔截 } //Service接口 實現類 public class AopServiceImpl implements IAopService{ private String name; public void withAop() throws Exception{ System.out.println("有AOP的函數運行。name:"+name); if(name.trim().length() == 0){ throw new AccountException("name屬性不能為空"); } } public void withoutAop() throws Exception{ System.out.println("沒有AOP的函數運行。"); } public void setName(String name){ this.name = name; } public String getName(){ return this.name; } }方法前攔截器,檢查name是否為空:
import org.springframework.aop.MethodBeforeAdvice; public class MethodBeforeInterceptor implements MethodBeforeAdvice{ //調用對象的方法前執行該方法 //參數分別為被調用的方法、被調用方法的參數、對象 public void before(Method method,Object [] args,Object instance) throws Throwable{ System.out.println("即將執行方法:"+method.getName()); // if(instance instanceof AopServiceImpl){ String name = ((AopServiceImpl)instance).getName(); if(name == null){ throw new NullPointerException("name不能為空"); } } } }返回后攔截器:
import org.springframework.aop.AfterReturningAdvice; public class MethodAfterInteceptor implements AfterReturningAdvice{ //參數分別為方法返回值、被調用方法、方法參數、被攔截的對象 public void afterReturning(Object value,Method method,Object [] args,Object instance) throws Throwable{ System.out.println("方法:"+method.getName()+"執行完畢,返回值為:"+value); } }異常攔截器捕獲異常 :
import org.springframework.aop.ThrowAdvice; public class ThrowsInterceptor implements ThrowAdvice{ //參數分別為被調用的方法、方法參數、對象實例、拋出的異常 //前三個參數可以省略,第四個參數是必須的,這樣設計是為了使開發者靈活地定義多個方法捕獲各種不同的異常 public void afterThrowing(Method method,Object [] args,Object instance,AccountException ex) throws Throwable { System.out.println("方法:"+method.getName()+"拋出了異常:"+ex); } public void afterThrowing(NullPointerException ex) throws Throwable { System.out.println("拋出了異常:"+ex); } }攔截器配置:
Spring無法將Service的實現類與攔截器直接組裝,因為沒有對應的setter、getter方法。安裝時借助的是Spring的代理類,把攔截器安裝到NameMatchMethodPointcutAdvisor中,把自動以的Service安裝到ProxyFactoryBean中,然后組裝到一塊。
切面Aspect:在本例中,方法withAop()、withoutAop()中都有一些代碼,這些代碼可以看做是AOP中的切面,可以將切面理解為模塊;
通知Advisor:本例的三個攔截器都是實現自某個接口,從類名上看就知道三個攔截器都是AOP中的通知。一旦Spring符合條件,就會派發出通知,即一些需要執行的代碼,能實現某種功能;
切入點Pointcut:在配置攔截器時,XML中只配置了withAop()方法使用攔截器,而withoutAop()方法沒有配置攔截器,這種配置是借助于org.springframework.aop.support. NameMatchMethodPointcutAdvisor完成的。這就是一個切入點,配置時可以使用通配符。該類說明上也帶有Advisor是因為它也是用通知實現的;
AOP的相關概念總結:
方面(Aspect):一個關注點的模塊化,這個關注點實現可能另外橫切多個對象。事務管理是J2EE應用中一個很好的橫切關注點例子。方面用spring的 Advisor或攔截器實現。
連接點(Joinpoint): 程序執行過程中明確的點,如方法的調用或特定的異常被拋出。
通知(Advice): 在特定的連接點,AOP框架執行的動作。各種類型的通知包括“around”、“before”和“throws”通知。通知類型將在下面討論。許多AOP框架包括Spring都是以攔截器做通知模型,維護一個“圍繞”連接點的攔截器鏈。Spring中定義了四個advice: BeforeAdvice, AfterAdvice, ThrowAdvice和DynamicIntroductionAdvice。
切入點(Pointcut): 指定一個通知將被引發的一系列連接點的集合。AOP框架必須允許開發者指定切入點:例如,使用正則表達式。 Spring定義了Pointcut接口,用來組合MethodMatcher和ClassFilter,可以通過名字很清楚的理解, MethodMatcher是用來檢查目標類的方法是否可以被應用此通知,而ClassFilter是用來檢查Pointcut是否應該應用到目標類上。
引入(Introduction): 添加方法或字段到被通知的類。 Spring允許引入新的接口到任何被通知的對象。例如,你可以使用一個引入使任何對象實現 IsModified接口,來簡化緩存。Spring中要使用Introduction, 可有通過DelegatingIntroductionInterceptor來實現通知,通過DefaultIntroductionAdvisor來配置Advice和代理類要實現的接口。
目標對象(Target Object): 包含連接點的對象。也被稱作被通知或被代理對象。
AOP代理(AOP Proxy): AOP框架創建的對象,包含通知。 在Spring中,AOP代理可以是JDK動態代理或者CGLIB代理。
織入(Weaving): 組裝方面來創建一個被通知對象。這可以在編譯時完成(例如使用AspectJ編譯器),也可以在運行時完成。Spring和其他純Java AOP框架一樣,在運行時完成織入。
總結
以上是生活随笔為你收集整理的【Spring学习】Spring的AOP模块应用详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Spring学习】IOC容器
- 下一篇: 【Spring学习】IoC、DI、AOP