为讲解例子,我们首先定义一个Performance接口:

 package aoptest;

 public interface Performance {
public void perform();
}

再定义一个该接口的实现:

 package aoptest;

 public class PianoPerform implements Performance {

     @Override
public void perform() {
// TODO Auto-generated method stub
System.out.println("i am playing piano");
} }

在创建切面之前,我们先来看一下切点表达式的用法,如图所示:

关于切点表达式的更多用法,可查看相关文档。

接着,我们使用注解定义一个切面,Audience类会在perform方法执行前后织入指定的方法

 package aoptest;

 import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*; @Aspect
public class Audience { @Pointcut("execution(** aoptest.Performance.perform(..))")
public void performance() {}
//performance()方法的实际内容并不重要,在这里它是空的。
//其实该方法本身只是一个标识,供@Pointcut注解依附
//不这样做的话,就需要在每个方法前都使用这个长点的表达式 @Before("performance()")
public void silenceCellPhones() {
System.out.println("Slience cell phones");
} @Before("performance()")
public void takeSeats() {
System.out.println("takeSeats");
} @AfterReturning("performance()")
public void applause() {
System.out.println("applause");
} @AfterThrowing("performance()")
public void demandRefund() {
System.out.println("demandRefund");
}
}
  • @Before:通知方法会在目标方法调用之前调用
  • @AfterReturning:通知方法在目标方法成功返回后调用
  • @AfterThrowing:通知方法在目标方法抛出异常后调用
  • @Around:通知方法会将目标方法封装起来



接着,进行测试,首先使用JavaConfig进行相关bean的配置:

 package aoptest;

 import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration
@EnableAspectJAutoProxy //启用aspectJ自动代理
@ComponentScan
public class AopConfig {
@Bean
public Audience audience() {
return new Audience();
} @Bean
Performance performance() {
return new PianoPerform();
}
}

然后,创建测试类:

 package aoptest;

 import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; //用于在测试开始时自动创建Spring上下文
@RunWith(SpringJUnit4ClassRunner.class)
//告诉上下文需要在AopConfig中加载配置
@ContextConfiguration(classes = { AopConfig.class })
public class PerformTest {
@Autowired
public Audience audience;
@Autowired
public Performance performance;
@Test
public void play() {
performance.perform();
}
}

测试结果,符合预期:

现在,我们利用@Around创建环绕通知,重新实现切面,可以达到相同的效果:

package aoptest;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*; @Aspect
public class Audience { @Pointcut("execution(** aoptest.Performance.perform(..))")
public void performance() {}
//performance()方法的实际内容并不重要,在这里它是空的。
//其实该方法本身只是一个标识,供@Pointcut注解依附
//不这样做的话,就需要在每个方法前都使用这个长点的表达式 @Around("performance()")
//ProceedingJoinPoint这个对象是必须有的,因为需要通过它来调用被通知的方法,使用proceed()方法
public void watchPerformance(ProceedingJoinPoint jp) {
System.out.println("Slience cell phones");
System.out.println("takeSeats");
try {
jp.proceed();
} catch (Throwable e) {
System.out.println("demandRefund");
}
System.out.println("applause");
}
}

当然,你也可以不调用proceed()方法,从而阻塞对通知方法的访问。

最新文章

  1. 切换debian8系统语言环境
  2. [转]Oracle VM VirtualBox虚拟机,Ubuntu虚拟机共享文件夹
  3. 使用mvn生成webapp失败,尚未找到原因
  4. 【leetcode】Implement strStr() (easy)
  5. Unity Sprite转Prefab
  6. c++关键字之#define typedef const
  7. a++累加
  8. CHARINDEX,PATINDEX,STUFF函数
  9. 教你记住ASP.NET WebForm页面的生命周期
  10. 在C#程序中模拟发送键盘按键消息
  11. JAVA多线程-初体验
  12. [Day23]IO(字节流、字符流)
  13. 新建VS工程与填坑:解决方案与项目不在同一目录
  14. day15-集合
  15. (转)清除已运行过Rancher和K8S的主机上的环境数据
  16. linux下&、nohup与screen的比较
  17. POJ 3254 Corn Fields状态压缩DP
  18. ES(1): Creat linux VM on Azure
  19. LeetCode题解之 two sum 问题
  20. 软工之404 Note Found 队选题报告

热门文章

  1. Qt移动应用开发(二):使用动画框架
  2. VB的程序如何破解
  3. LeetCode 953. Verifying an Alien Dictionary (验证外星语词典)
  4. poj2011
  5. MODULE_DEVICE_TABLE的理解【转】
  6. Kaggle "Microsoft Malware Classification Challenge"——就是沙箱恶意文件识别,有 Opcode n-gram特征 ASM文件图像纹理特征 还有基于图聚类方法
  7. 【高德地图API】注册密钥
  8. IBatis异常: Cannot find class: VARCHAR
  9. 那些有意思的Github
  10. PCB genesis SET取中心点--算法实现