</pre><pre name="code" class="java">package com.entity;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class Audience {
//該註解用於定義一個可以在@Aspect切面可以重用的切點,將切點名稱作爲參數的值賦給了所有的通知註解
@Pointcut("execution(* com.Performer.perform(..))")
public void performance(){
}
@Before("performance()")
public void takeSeats(){
System.out.println("觀衆請入座!");
}
@Before("performance()")
public void turnOffCellPhones(){
System.out.println("入座後請關閉您的手機!");
}
@AfterReturning("performance()")
public void applaund(){
System.out.println("表演的很好,掌聲!");
}
@AfterThrowing("performance()")
public void demandRefund(){
System.out.println("表演的太次了,要求返錢!");
}
//講方法作爲環繞通知作用於切點
<span style="white-space:pre"> </span>@Around("performance()")
public void watchPerformance(ProceedingJoinPoint joinPoint){
try{
System.out.println("觀衆請入座");
System.out.println("入座後請關閉您的手機!");
long start=System.currentTimeMillis();
//很重要,如果沒有,將會阻止被通知的方法的調用
joinPoint.proceed();
for(int i=1;i<100000000;i++){
}
long end=System.currentTimeMillis();
System.out.println("表演的很好,掌聲!");
System.out.println("這場表演一共花費:"+(end-start));
}catch(Throwable t){
System.out.println("下去!把我們的錢還給我們!");
}
}
}
(1)Audience類現在已經使用@AspectJ註解進行了標註,標明瞭Audience不僅是一個POJO還是一個切面
(2)@Pointcut註解:定義一個可以在@AspectJ切面可以重用的切點。該註解的值:是一個切點表達式--這裏標示改切點必須匹配Performer的perform()方法。切點的名稱源於註解所應用的方法名稱
(3)@Before:標示前置通知方法
(4)@AfterReturning:標示後置通知方法
(5)@AfterThrowing:標示異常時通知方法
(6)@Around:方法作爲環繞通知作用於切點
看一下我們的接口:Performer
package com;
import com.exception.PerformanceExcetion;
public interface Performer {
void perform() throws PerformanceExcetion;
}
接口的實現類:Juggler
package com.entity;
import com.Performer;
import com.exception.PerformanceExcetion;
public class Juggler implements Performer{
private int beanBags=3;
public Juggler(){
}
public Juggler (int beanBags){
this.beanBags=beanBags;
}
@Override
public void perform() throws PerformanceExcetion {
System.out.println("Juggler(雜技師) "+ beanBags +" beanBags ");
}
}
接下來我們需要在配置文件中註明:我們的Bean:
<bean id="audience" class="com.entity.Audience"/>
<bean id="juggler" class="com.entity.Juggler"></bean>
接口不需要聲明Bean最後一件事情:讓Spring將Audience應用爲一個切面,我們需要在Sping上下文中聲明一個自動代理Bean,該Bean知道如何把@AspectJ註解所標註的Bean轉爲代理通知:
<aop:aspectj-autoproxy/>
測試用例:
package com;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class springTest {
public static void main(String[] args) {
ApplicationContext cxt=new ClassPathXmlApplicationContext(
"classpath:/spring/spring.xml");
Performer performer=(Performer)cxt.getBean("juggler");
performer.perform();
}
}
輸出結果:
觀衆請入座
入座後請關閉您的手機!
觀衆請入座!
入座後請關閉您的手機!
Juggler(雜技師) 3 beanBags
表演的很好,掌聲!
這場表演一共花費:30
表演的很好,掌聲!