这个是承接五的,这部分主要的内容是在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 切面注入依赖。这里就不写了,我感觉一般也用不到,用到的时候在补充吧。。。
原文地址:https://www.cnblogs.com/ssh-html/p/9747585.html
时间: 2024-11-11 11:21:19