六、面向切面的spring(2)
阿新 • • 發佈:2018-10-08
class 播放 iso 類型 tro interface proc 透明 功能
這個是承接五的,這部分主要的內容是在XML中聲明切面。
一、在XML中聲明切面
讓我們先看一下spring中的AOP配置元素有哪些:
AOP配置元素 | 用途 |
<aop:advisor> | 定義AOP通知器 |
<aop:after> | 定義AOP後置通知(不管被通知的方法是否成功) |
<aop:after-returning> | 定義AOP返回通知 |
<aop:around> | 定義AOP環繞通知 |
<aop:aspect> | 定義一個切面 |
<aop:aspectj-autoproxy> | 啟用@AspectJ註解驅動切面 |
<aop:before> | 定義一個 |
<aop:config> | 頂層的AOP配置元素,大多數的 |
<aop:declare-parents> | 以透明的方式為被通知的對象引入額外的接口 |
<aop:pointcut> | 定義一個切點 |
1 //聲明的Audience類 2 package concert; 3 public class Audience { 4 public void silenceCellPhones(){ 5 System.out.println("Silence cell phones");6 } 7 8 public void takeSeats(){ 9 System.out.println("Taking seats"); 10 } 11 12 public void applause(){ 13 System.out.println("CLAP CLAP CLAP!!!"); 14 } 15 16 public void demadRefund(){ 17 System.out.println("Demanding a refund"); 18 } 19 }
1、聲明前置和後置通知
通過XML方式將無註解的Audience聲明為切面
1 <aop:config> 2 //引用audience bean 3 <aop:aspect ref="audience"> 4 <aop:before 5 pointcut="execution(** concert.Performance.perform(..))" 6 method="silenceCellPhone" /> 7 8 <aop:before 9 pointcut="execution(** concert.Performance.perform(..))" 10 method="takeSeats" /> 11 12 <aop:after-returning 13 pointcut="execution(** concert.Performance.perform(..))" 14 method="applause" /> 15 16 <aop:after-throwing 17 pointcut="execution(** concert.Performance.perform(..))" 18 method="demandRefund" /> 19 </aop:aspect> 20 </aop:config> 21 22 //使用<aop:pointcut> 定義命名切點 23 <aop:config> 24 //引用audience bean 25 <aop:aspect ref="audience"> 26 <aop:point 27 id="performance" 28 expression="execution(** concert.Performance.perform(..))" 29 /> 30 <aop:before 31 pointcut="performance" 32 method="silenceCellPhone" /> 33 34 <aop:before 35 pointcut="performance" 36 method="takeSeats" /> 37 38 <aop:after-returning 39 pointcut="performance" 40 method="applause" /> 41 42 <aop:after-throwing 43 pointcut="performance" 44 method="demandRefund" /> 45 </aop:aspect> 46 </aop:config>
2、聲明環繞通知
1 package concert; 2 import org.aspectj.lang.PreceedingJoinPoint; 3 4 public class Audience{ 5 public void watchPerformance(PreceedingJoinPoint jp){ 6 try{ 7 System.out.println("Sliencing cell phones"); 8 System.out.println("Taking seats"); 9 jp.proceed(); 10 System.out.println("CLAP CLAP CLAP!!!"); 11 }catch(Throwable e){ 12 System.out.println("Demanding a refund"); 13 } 14 } 15 } 16 17 //xml中配置環繞通知 18 <aop:config> 19 <aop:aspect ref="audience"> 20 <aop:pointcut id="performance" experssion="execution(** concert.Performance.perform(..))" /> 21 <aop:around pointcut-ref="performance" method="watchPerformance" /> 22 </aop:aspect> 23 </aop:config>
3、為通知傳遞參數
//使用參數化的通知來記錄磁道播放的次數 package soundsystem; import java.util.HashMap; import java.util.Map; public class TrackCounter { private Map<Integer,Integer> trackCounts = new HashMap<Integer,Integer>(); public void trackPlayed(int trackNumber) {} public void countTrack(int trackNumber){ int currentCount = getPlayCount(trackNumber); trackCounts.put(trackNumber, currentCount +1); } public int getPlayCount(int trackNumber){ return trackCounts.countainsKey(trackNumber) ? trackCounts.get(trackNumber) : 0; } } //在XML 中將TrackCounter配置為參數化的切面 <bean id="trackCounter" class="soundsystem.TrackCounter " /> <bean id="cd" class="soundsystem.BlackDisc" > <property name="title" value="此時此刻" /> <property name="artist" value="許巍" /> <property name="tracks" > <list> <value>空谷幽蘭</value> <value>愛情</value> <value>此時此刻</value> <value>靈巖</value> <value>救贖之旅</value> <value>心願</value> <value>逍遙行</value> <value>喜悅</value> <value>世外桃源</value> <value>出離</value> </list> </property> </bean> <aop:config> <aop:aspect ref="trackCounter"> <aop:pointcut id="trackPlayed" expression="execution(* soundsystem.CompactDisc.playerTrack(int)) and args(trackNumber)" /> <aop:before pointcut-ref="trackPlayed" method="countTrack" /> </aop:aspect> </aop:config>
註意:我們使用了前面相同的aop命名空間XML元素,它們會將POJO聲明為切面。唯一的區別是切點表達式中包含了一個參數,這個參數會傳遞到通知的方法中。
4、通過切面引入新功能
<aop:aspect> <aop:declare-parents types-matching="concert.Performance" implement-interface="concert.Encoreable" default-impl="concert.DefaultEncoreable" /> </aop:aspect>
<aop:declare-parents>聲明了此切面所通知的bean要在它的對象層次結構擁有新的父類型。具體到本例中,類型匹配Performance接口(由types-matching屬性指定)的那些bean在父類結構中會增加Encoreable接口(由implement-interface屬性指定)。
二、註入Aspect切面
當springAOP不能滿足需求時,我們必須轉向更為強大的AspectJ。這裏主要註意的是如何使用spring為AspectJ 切面註入依賴。這裏就不寫了,我感覺一般也用不到,用到的時候在補充吧。。。
六、面向切面的spring(2)