8.4.5 基于注解的 零配置 方式 5. After增强处理

8.4.5 基于注解的 零配置 方式 5. After增强处理

Spring还提供了一个After增强处理,它与AfterReturning增强处理有点相似,但也有区别。

  1. AfterReturning增强处理只有在目标方法成功执行结束后才会被织入
  2. After增强处理不管目标方法如何结束,它都会被织入PS:方法结束包括成功执行结束遇到异常中止这两种情况。

因为不论一个方法是如何结束的, After增强处理都会被织入,因此After增强处理必须准备处理正常返回异常返回两种情况,这种增强处理通常用于释放资源。After增强处理有点类似于finally块。

使用@After注解修饰一个方法,即可将该方法转成After增强处理。使用@After注解时需要指定个value属性,该属性值用于指定该增强处理被织入的切入点,既可是一个已有的切入点,也可直接指定切入点表达式。

程序示例

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

下面的程序将定义一个After增强处理。

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

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

// 定义一个切面
@Aspect
public class ReleaseAspect
{
// 匹配org.crazyit.app.service包下所有类的
// 所有方法的执行作为切入点
@After("execution(* org.crazyit.app.service.*.*(..))")
public void release()
{
System.out.println("模拟方法结束后的释放资源...");
}
}

上面程序中的粗体字代码定义了一个After增强处理,不管切入点的目标方法如何结束,该增强处理都会被织入。该示例程序的目标对象依然使用HellolmplWorldImpl类, HelloImpl组件中的deleteUser()方法会因为抛出异常而结束。
主程序依然使用长度-2作为deleteUser()方法的参数,此时将可以看到如图8.3所示的效果。

1
2
3
4
5
6
7
8
9
执行Hello组件的addUser添加用户:悟空
模拟方法结束后的释放资源...
模拟方法结束后的释放资源...
Exception in thread "main" java.lang.IllegalArgumentException: 被删除用户的id不能小于0:-2
at org.crazyit.app.service.impl.HelloImpl.deleteUser(HelloImpl.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
......

After增强特别特别适合用于资源回收

从图8.13中可以看出,虽然deleteUser方法因为legalArgumentException异常结束,但After增强处理依然被正常织入。由此可见,After增强处理的作用非常类似于异常处理中finally块的作用—无论如何,它总会在方法执行结束之后被织入,因此特别适用于进行资源回收。