Aspect概述
AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
- AspectJ是一个基于Java语言的AOP框架
- Spring2.0以后新增了对AspectJ切点表达式支持
- AspectJ注解 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面
- 常用自定义内容开发。例如:性能监控等
1 | //自定义切面类 |
切入点表达式
execution(表达式) 用于确定方法(可以为不同的方法进行确定)
修饰符
public 修饰符公共
* 任意修饰符
返回值
String 返回字符串
* 返回任意
包
com.jessyon.service 指定包(某一个模块)
com.jessyon.*.service 子模块(子文件夹)任意
com.jessyon.service.. service目录当前目录 ,以及子目录(孙子)
com.jessyon.*.service.. jessyon下所有的子模块,service目录所有目录
类
UserService 指定类名
User* 以User开头类
*Service 以Service结尾类
* 任意类
方法
addUser 指定方法
add* add开头方法
*User 以User结尾方法
* 任意方法
参数列表
() 没有参数
(int) 一个参数
(int,int) 两个参数
(..) 参数任意
AspectJ通知类型
定义6中通知类型,掌握1种,知道4种,了解1种。
- before:前置通知(应用:各种校验) 在方法执行前执行,如果通知抛出异常,阻止方法运行
- afterReturning:后置通知(应用:常规数据处理) 方法正常返回后执行,如果方法中抛出异常,通知无法执行。必须在方法执行后才执行,所以可以获得方法的返回值。
- around:环绕通知(应用:十分强大,可以做任何事情) 方法执行前后分别执行,可以阻止方法的执行
- afterThrowing:抛出异常通知(应用:包装异常信息) 方法抛出异常后执行,如果方法没有抛出异常,无法执行
- after:最终通知(应用:清理现场) 方法执行完毕后执行,无论方法中是否出现异常
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70public class MyAspect{
public void myBefore(JoinPoint joinPoint){
System.out.println("前置通知 :" + joinPoint.getSignature().getName());
}
public void myAfterReturning(JoinPoint joinPoint,Object ret){
System.out.println("后置通知:" + joinPoint.getSignature().getName() + " , " + ret);
}
public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕前");
//执行目标方法
Object obj = joinPoint.proceed();
System.out.println("环绕后");
return obj;
}
public void myAfterThrowing(JoinPoint joinPoint, Throwable e){
System.out.println("抛出异常通知:" + joinPoint.getSignature().getName() + " , " + e.getMessage());
}
public void myAfter(JoinPoint joinPoint){
System.out.println("最终"+ joinPoint.getSignature().getName() );
}
}
//注解版本
@Component
@Aspect
public class MyAspect{
//定义:公共切入点表达式。之后使用直接调用方法名
@Pointcut("execution(* com.jessyon.annotation.*.*(..))")
private void myPointCut(){}
//@Before("execution(* com.jessyon.annotation.*.*(..))")
public void myBefore(JoinPoint joinPoint){
System.out.println("前置通知 :" + joinPoint.getSignature().getName());
}
//@AfterReturning(value="execution(* com.jessyon.annotation.*.*(..))",returning="ret")
public void myAfterReturning(JoinPoint joinPoint,Object ret){
System.out.println("后置通知:" + joinPoint.getSignature().getName() + " , " + ret);
}
//@Around("myPointCut()")
public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕前");
//执行目标方法
Object obj = joinPoint.proceed();
System.out.println("环绕后");
return obj;
}
//@AfterThrowing(value="myPointCut()",throwing="e")
public void myAfterThrowing(JoinPoint joinPoint, Throwable e){
System.out.println("抛出异常通知:" + joinPoint.getSignature().getName() + " , " + e.getMessage());
}
@After("myPointCut()")
public void myAfter(JoinPoint joinPoint){
System.out.println("最终"+ joinPoint.getSignature().getName() );
}
}
<!-- 注解aspectj 必须进行配置 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>