@AspectJ注解于类名上来声明这个类是一个切面类
AspectJ 简介
- AspectJ是一个基于Java语言的AOP框架
- Spring2.0以后新增了对AspectJ切点表达式支持
- @AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面
- 新版本Spring框架,建议使用AspectJ方式来开发AOP
- 使用AspectJ 需要导入Spring AOP和 AspectJ相关jar包
1 |
|
切入点表达式部分关键词
execution:用于匹配子表达式
1
2
3//匹配com.cjm.model包及其子包中所有类中的所有方法,返回类型任意,方法参数任意
public void before(){}within:用于匹配连接点所在的Java类或者包
1
2
3
4
5
6//匹配Person类中的所有方法
public void before(){}
//匹配com.cjm包及其子包中所有类中的所有方法
public void before(){}this:用于向通知方法中传入代理对象的引用
1
2
3
4
public void beforeAdvide(JoinPoint point, Object proxy){
//处理逻辑
}target:用于向通知方法中传入目标对象的引用
1
2
3
4
public void beforeAdvide(JoinPoint point, Object proxy){
//处理逻辑
}args:用于将参数传入到通知方法中。
1
2
3
4
public void beforeAdvide(JoinPoint point, int age, String username){
//处理逻辑
}@AspectJ的不同通知类型
所有通知的
value
属性都是Pointcut
,可以直接写表达式,也可以写成一个被@Pointcut
注解过的方法,类似于下面的例字- 顺带介绍
@Pointcut
注解的格式:private void 无参数方法,方法名为切点名
,且当通知多个切点时,可以使用|| 进行连接
1
2
3
4
5
6
7
8
9
10
11
12
private void myPointcut() {
}
public void before(JoinPoint joinPoint) {
//doSomething
}
//---------------等效于----------------
public void before(JoinPoint joinPoint) {
//doSomething
}- 顺带介绍
@Before 前置通知,相当于BeforeAdvice
可以在
before()
方法中添加JoinPoint joinPoint
,这样就可以在切面方法中获得切入点信息1
2
3
4
public void before(JoinPoint joinPoint) {
//doSomething
}@AfterReturning 后置通知,相当于AfterReturningAdvice
- 若目标方法有返回值,就需要给
@AfterReturning
注释中的returning
属性赋值,方法添加一个Object returnObj
参数,这样可以在切面方法中获得目标方法的返回值 - 这里
returning = "returnObj"
中"returnObj"
字符串的值可以任取,但要保证函数中传入的参数名与之相同
1
2
3
4
public void afterReturing(Object returnObj) {
//doSomething
}- 若目标方法有返回值,就需要给
@Around 环绕通知,相当于MethodInterceptor
- 切面方法的返回值就是代理方法执行返回值,一般将返回值写为
Object
- 切面方法的返回值就是代理方法执行返回值,一般将返回值写为
参数必须包含
ProceedingJoinPoint
,它的作用是调用拦截目标方法执行- 如果不调用
ProceedingJoinPoint
的proceed
方法,那么目标方法就不会被执行
- 如果不调用
ProceedingJoinPoint 对象的 proceed() 需要捕获异常,并且这里如果产生异常(即目标方法产生异常)
1
2
3
4
5
6
7
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
//doSomething 假设这里开启事务
Object obj = joinPoint.proceed(); // 执行目标方法 假设为数据库的操作
//doSomething 假设这里提交事务
return obj;
}@AfterThrowing异常抛出通知,相当于ThrowAdvice
这里的
throwing
属性使用方法与@AfterReturning
注释中的returning
属性类似,可以让代理方法得到目标方法所抛出的异常1
2
3
4
public void afterThrowing(Throwable e) {
//doSomething 假设回滚事务
}@After 最终final通知,不管是否异常,该通知都会执行
@DeclareParents 引介通知,相当于IntroductionInterceptor
通过Value属性定义切点(execution函数)
在通知中通过value属性定义切点,通过execution函数,可以定义切点的方法切入
1. 语法:
execution(<访问修饰符>? <返回类型> <方法名>(<参数>)<异常>)
2. 介绍这里使用的一些基本通配符的含义:
*
匹配任意数量的字符+
匹配制定数量的类及其子类,可用于表示实现此接口的所有类..
匹配本包及其子包&&、||、!
切入点表达式支持逻辑运算符
3. 例:
匹配所有类public方法
execution(public * *(..))
匹配指定包下所有类方法
execution(* com.imooc.dao.*(..))
不包含子包execution(* com.imooc.dao..*(..))
..*
表示包、子孙包下所有类
匹配指定类所有方法
execution(* com.imooc.service.UserService.*(..))
匹配实现特定接口所有类方法
execution(* com.imooc.dao.GenericDAO+.*(..))
匹配所有save开头的方法
execution(* save*(..))