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
,故导致程序中止。