Spring AOP之AfterThrowing增强处理
Posted nickup
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring AOP之AfterThrowing增强处理相关的知识,希望对你有一定的参考价值。
Spring AOP(三)之AfterThrowing增强处理
使用@AfterThrowing注解可以修饰AfterThrowing增强处理,AfterThrowing增强处理主要用于处理程序中未处理的异常。使用@AfterThrowing注解时可指定如下的常用属性:
1) pointcut/value:这两个属性的作用是一样的,它们都用于指定该切入点对应的切入表达式。一样既可是一个已有的切入点,也可以直接定义切入点表达式。当指定了pointcut属性后,value属性值将会被覆盖。
2) throwing:该属性指定一个形参名,用于表示Advice方法中可定义与此同名的形参,该形参可用于访问目标方法抛出的异常。除此之外,在Advice方法中定义该参数时,指定的类型,会限制方法必须抛出指定类型的异常。
下面,我们定义于个AfterThrowing增强处理。
- @Aspect
- public class RepairAspect
- {
- // 匹配com.owenapp.service.impl包下所有类的、
- // 所有方法的执行作为切入点
- @AfterThrowing(throwing="ex"
- , pointcut="execution(* com.owen.app.service.impl.*.*(..))")
- // 声明ex时指定的类型会限制目标方法必须抛出指定类型的异常
- // 此处将ex的类型声明为Throwable,意味着对目标方法抛出的异常不加限制
- public void doRecoveryActions(Throwable ex)
- {
- System.out.println("目标方法中抛出的异常:" + ex);
- System.out.println("模拟Advice对异常的修复...");
- }
- }
@Aspect public class RepairAspect { // 匹配com.owenapp.service.impl包下所有类的、 // 所有方法的执行作为切入点 @AfterThrowing(throwing="ex" , pointcut="execution(* com.owen.app.service.impl.*.*(..))") // 声明ex时指定的类型会限制目标方法必须抛出指定类型的异常 // 此处将ex的类型声明为Throwable,意味着对目标方法抛出的异常不加限制 public void doRecoveryActions(Throwable ex) { System.out.println("目标方法中抛出的异常:" + ex); System.out.println("模拟Advice对异常的修复..."); } }
正如上面所看到的,程序中使用@AfterThrowing注解时,指定了一个throwing属性,该属性值为ex,这允许在增强处理方法(doRecoveryActions()方法)中定义名为ex的形参,程序可通过该形参访问目标方法所抛出的异常。下面我们定义一个HelloImpl.java。
- @Component("hello")
- public class HelloImpl implements Hello
- {
- // 定义一个简单方法,模拟应用中的业务逻辑方法
- public void foo()
- {
- System.out.println("执行Hello组件的foo()方法");
- }
- // 定义一个addUser()方法,模拟应用中的添加用户的方法
- public int addUser(String name , String pass)
- {
- System.out.println("执行Hello组件的addUser添加用户:" + name);
- if(name.length() < 3 || name.length() > 10)
- {
- throw new IllegalArgumentException("name参数的长度必须大于3,小于10!");
- }
- return 20;
- }
- }
@Component("hello") public class HelloImpl implements Hello { // 定义一个简单方法,模拟应用中的业务逻辑方法 public void foo() { System.out.println("执行Hello组件的foo()方法"); } // 定义一个addUser()方法,模拟应用中的添加用户的方法 public int addUser(String name , String pass) { System.out.println("执行Hello组件的addUser添加用户:" + name); if(name.length() < 3 || name.length() > 10) { throw new IllegalArgumentException("name参数的长度必须大于3,小于10!"); } return 20; } }
写个测试类:
- public class BeanTest
- {
- public static void main(String[] args)
- {
- // 创建Spring容器
- ApplicationContext ctx = new
- ClassPathXmlApplicationContext("beans.xml");
- Hello hello = ctx.getBean("hello" , Hello.class);
- hello.foo();
- hello.addUser("owen" , "7788");
- }
- }
public class BeanTest { public static void main(String[] args) { // 创建Spring容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); Hello hello = ctx.getBean("hello" , Hello.class); hello.foo(); hello.addUser("owen" , "7788"); } }
执行结果:
- [java] 信息:Loading XML bean definitions from class path resource…
- [java]执行Hello组件的foo()方法
- [java]执行Hello组件的addUser添加用户:owen
- [java]目标方法中抛出的异常:java.lang.IllegalArgumentArgumentException:name参数的长度必须大于3,小于10!
- [java]Exception in thread “main” java.lang.IllegalArgumentException:name参数的长度必须大于3,小于10!
- …….
[java] 信息:Loading XML bean definitions from class path resource… [java]执行Hello组件的foo()方法 [java]执行Hello组件的addUser添加用户:owen [java]目标方法中抛出的异常:java.lang.IllegalArgumentArgumentException:name参数的长度必须大于3,小于10! [java]Exception in thread “main” java.lang.IllegalArgumentException:name参数的长度必须大于3,小于10! …….
总结:
AOP的AfterThrowing处理虽然可以对目标方法的异常进行处理,但这种处理与直接使用catch捕捉不同,catch捕捉意味着完全处理该异常,如果catch块中没有重新抛出新的异常,则该方法可能正常结束;而AfterThrowing处理虽然处理了该异常,但它不能完全处理异常,该异常依然会传播到上一级调用者,即JVM。
以上是关于Spring AOP之AfterThrowing增强处理的主要内容,如果未能解决你的问题,请参考以下文章
Spring:Aop before after afterReturn afterThrowing around 的原理
Spring AOP @before@after@around@afterreturning@afterthrowing执行顺序
[技术分享]20171214_spring_@Before @After @AfterReturning @Around @AfterThrowing spring aop 的advise(通知)(