8.4.5 基于注解的 零配置 方式 4. 定义AfterThrowing增强处理
使用@AfterThrowing注解可修饰AfterThrowing增强处理, AfterThrowing增强处理主要用于处理程序中未处理的异常。
使用@AfterThrowing注解时可指定如下两个常用属性。
| 属性 | 描述 | ||
|---|---|---|---|
| pointcut或者value | 这两个属性的作用是一样的,它们都用于 指定该切入点对应的切入表达式。样既可是一个已有的切入点,也可直接定义切入点表达式。当指定了pointcut属性值后,value属性值将会被覆盖。 | ||
| throwing | 该属性值指定一个形参名,用于表示 Advice方法中可定义与此同名的形参,该形参可用于访问目标方法抛出的异常。除此之外,在Advice方法中定义该形参时如果指定了类型,则会限制目标方法必须是抛出该类型的异常的方法。 | ||
| ## 程序示例 ## | |||
| 
 | 
下面的程序定义了一个AfterThrowing增强处理。
| 1 | package org.crazyit.app.aspect; | 
正如在上面的程序中看到的,程序中使用@AfterThrowing注解时指定了一个throwing属性,该属性值为ex,这允许在增强处理方法doRecoveryActions中定义名为ex的形参,程序可通过该形参访问目标方法所抛出的异常。
将前面示例中的HelloImpl.java类做一些修改,用于模拟程序抛出异常,修改后的Hellolmpl.java类的代码如下:
| 1 | package org.crazyit.app.service.impl; | 
上面程序中的deleteUser()方法可能抛出异常,当调用deleteUser()方法传入的参数小于0时,deleteUser()方法就会抛出异常,且该异常没有被任何程序所处理,故Spring AOP会对该异常进行处理。
该示例的主程序略作改变,将调用deleteUser()方法的参数改为-2。运行该主程序,将看到如下效果。
| 1 | 执行Hello组件的addUser添加用户:悟空 | 
throwing属性增强处理方法接收异常的参数
可以看到的,@AfterThrowing注解的throwing属性中指定的参数名必须与增强处理方法内的一个形参对应。当目标方法抛出一个未处理的异常时,该异常将会传给增强处理方法对应的参数。
使用throwing属性限定触发的异常类型
使用throwing属性还有一个额外的作用:它可用于限定切入点只匹配指定类型的异常;假如在上面的doRecoveryActions()方法中定义了ex形参的类型是NullPointerException,则该切入点只匹配抛出NullPointerException异常的方法。上面doRecoveryActions方法的ex形参类型是Throwable,这表明该切入点可匹配拋出任何异常的情况。
AOP的AfterThrowing处理与catch语句的不同
AOP的AfterThrowing处理虽然可以对目标方法的异常进行处理,但这种处理与直接使用catch捕捉不同:catch捕捉意味着完全处理该异常,如果catch块中没有重新抛出新异常,则该方法可以正常结束;AfterThrowing处理虽然处理了该异常,但它不能完全处理该异常,该异常依然会传播到上一级调用者,在本示例程序中异常直接传播到JVM,故导致程序中止。