8.4.5 基于注解的 零配置 方式 3. 定义AfterReturning增强处理

8.4.5 基于注解的 零配置 方式 3. 定义AfterReturning增强处理

类似于使用@Before注解可修饰Before增强处理,使用@AfterReturning可修饰AfterReturning增强处理, AfterReturning增强处理将在目标方法正常完成后被织入

@AfterReturning注解属性

使用@AfterReturning注解可指定如下两个常用属性。

属性 描述
pointcut或者value 这两个属性的作用是一样的,它们都用于指定该切入点对应的切入表达式。样既可是一个已有的切入点,也可直接定义切入点表达式。当指定了pointcut属性值后, value属性值将会被覆盖。
returning 该属性值指定一个形参名,用于表示Advice方法中可定义与此同名的形参,**该形参可用于访问目标方法的返回值**。除此之外,在Advice方法中定义该形参(代表目标方法的返回值)时指定具体类型,会限制目标方法必须返回该类型的值

程序示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\AfterReturning
└─src\
├─beans.xml
├─lee\
│ └─BeanTest.java
└─org\
└─crazyit\
└─app\
├─aspect\
│ └─LogAspect.java
└─service\
├─Hello.java
├─impl\
│ ├─HelloImpl.java
│ └─WorldImpl.java
└─World.java

下面的程序定义了一个AfterReturning增强处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package org.crazyit.app.aspect;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;

// 定义一个切面
@Aspect
public class LogAspect
{
// 匹配org.crazyit.app.service.impl包下所有类的、
// 所有方法的执行作为切入点
@AfterReturning(
returning = "rvt",
pointcut = "execution(* org.crazyit.app.service.impl.*.*(..))"
)
// 声明rvt时指定的类型会限制目标方法必须返回指定类型的值或没有返回值
// 此处将rvt的类型声明为Object,意味着对目标方法的返回值不加限制
public void log(Object rvt)
{
System.out.println("获取目标方法返回值:" + rvt);
System.out.println("模拟记录日志功能...");
}
}

正如在上面的程序中看到的,程序中使用@AfterReturning注解时,指定了一个returning属性,该属性值为rvt,这表明允许在Advice方法(log()方法)中定义名为rvt的形参,程序可通过rvt形参来访问目标方法的返回值

运行该应用的主程序,控制台输出如下:

1
2
3
4
5
6
7
8
9
10
执行Hello组件的addUser添加用户:孙悟空
获取目标方法返回值:20
模拟记录日志功能...
执行Hello组件的deleteUser删除用户:1
获取目标方法返回值:null
模拟记录日志功能...
执行World组件的bar()方法
获取目标方法返回值:null
模拟记录日志功能...

returning属性接收目标方法的返回值

@AfterReturning注解的returning属性所指定的形参名必须对应于增强处理中的一个形参名,当目标方法执行返回后,返回值作为相应的参数值传入增强处理方法

returning属性限制切入点只匹配特定返回值的方法

使用returning属性还有一个额外的作用:它可用于限定切入点只匹配具有对应返回值类型的方法,假如在上面的log()方法中定义rvt形参的类型是String,则该切入点只匹配org.crazyit.appservice.impl包下返回值类型为**String的方法或者没有返回值的方法**。当然,上面log()方法的rvt形参的类型是Object,这表明该切入点可匹配任何返回值类型的方法.

AfterReturning增强不能改变目标方法的返回值

注意:虽然AfterReturning增强处理可以访问到目标方法的返回值,但它不可以改变目标方法的返回值