Spring框架AOP配置异常和环绕通知(一)

本文详细介绍了Spring框架AOP中的异常通知和环绕通知配置。首先回顾了Spring AOP通知类型,包括AfterReturning和AfterThrowing。接着,通过具体步骤展示了如何配置异常通知,强调了异常类型需与切点抛出的异常类型一致。最后,解释了环绕通知的概念,并演示了如何配置和实现环绕通知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在之前的博客中,我已经给大家讲解了Spring框架中AOP的两种实现方式(Schema-based和AspectJ),并分别简单配置了它们的前后置通知。今天给大家补充其它的两种通知配置方法——异常和环绕通知,首先给大家回顾一下Spring框架中AOP有哪些通知类型:

通知类型接口描述
Around(环绕)org.aopalliance.intercept.MethodInterceptor拦截对目标方法调用
Before(前置)org.springframework.aop.MethodBeforeAdvice在目标方法执行前调用
After(后置)org.springframework.aop.AfterReturningAdvice在目标方法执行后调用
Throws(异常)org.springframework.aop.ThrowsAdvice当目标方法抛出异常时调用

其中后置通知还分为AfterReturning(返回通知)和AfterThrowing(异常通知)。

AfterReturning(返回通知):仅在目标方法执行成功后执行

AfterThrowing(异常通知):在目标方法抛出异常退出时执行

具体步骤

1.异常通知

所谓异常通知,只有当切点方法出现异常时才能够触发异常通知,否则是无效的。可是在Spring中只有AspectJ提供了异常通知的方法,而在Schema-based中想要配置异常通知,需要按照特定的要求自己去编写一个方法,来实现它。

首先新建一个类去实现throwsAdvice接口,但是它里面没有实现方法。我们需要到官方文档中去找一下

在官方文档中,我们可以看到,提供的方法都实现了ThrowsAdvice这个接口。先写一个异常通知类,类中的方法必须命名为afterThrowing,不然程序会报错。如下:

package a.b.advice;

import java.lang.reflect.Method;

import javax.servlet.ServletException;

import org.springframework.aop.ThrowsAdvice;

public class MyThrow implements ThrowsAdvice{
	public void afterThrowing(Exception ex) throws Throwable {
        System.out.println("Schema-based方式执行异常通知");
    }
//	public void afterThrowing(Method m, Object[] args, Object target, ServletException ex) {
//        System.out.println("执行异常通知");
//    }
}

这个官方文档为我们提供了两种参数方式,规定必须是一个或者四个,详细可以看文档。

在ApplicationContext.xml中配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="mythrow" class="a.b.advice.MyThrow"></bean>
    <aop:config>
        <aop:pointcut expression="execution(* a.b.test.Demo.demo1())" id="mypoint"/>
        <aop:advisor advice-ref="mythrow" pointcut-ref="mypoint"/>
        <!-- <aop:aspect ref="mythrow">
        	<aop:pointcut expression="execution(* a.b.test.Demo.demo1())" id="mypoint"/>
        	<aop:after-throwing method="afterThrowing" throwing="ex" point-ref="mypoint"/>
        </aop:aspect> -->
    </aop:config>
    <bean id="demo" class="a.b.test.Demo"></bean>
    <!-- <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> -->
</beans>

Demo类和测试

package a.b.test;

public class Demo {
	public void demo1() throws Exception{
		int i = 5/0;
		System.out.println("demo1");
	}
}
package a.b.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		Demo demo = ac.getBean("demo",Demo.class);
		try {
			demo.demo1();
		} catch (Exception e) {
			// TODO Auto-generated catch block
//			e.printStackTrace();
		}
	}
	
}

在配置异常通知时,我使用了官方文档提供的方法。Demo类不报异常时,能够输出结果。当出现异常时,仍然输出了语句,但是没有结果。我重写类和方法,检查了配置文件。当时没有发现问题,我猜想正常应该是需要回调通知类中的afterThrowing方法。可是这个方法没有回调上,于是在配置文件后又加了一个<aop:aspectj-autoproxy>标签。然而并没有什么卵用,重新翻看官方文档。看了Schema-based和AspectJ中所有的通知配置,AspectJ是用注释实现的通知配置,Schema-based全都是在<aop:aspect>标签当中配置的。于是我又按照官方的要求配置了一遍,还是没什么卵用。我试着把异常类型改了一下,结果奏效。由此得出,官方给的配置示例当中的异常类型,我们自己在编写的时候。不能拿它来使用。代码里面写的是一个算术异常类,我给它接收了一下,放到了MyThrow中。结果可以输出。得出结论异常类型一定要与切点所报的异常类型一致,不然没用。

2.环绕通知

什么是环绕通知。就是把前置通知和后置通知都写到一个通知类中,这就组成了环绕通知。

新建一个类实现MethodInterceptor接口

package a.b.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MyAround implements MethodInterceptor{

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		System.out.println("环绕-前置");
		Object result = arg0.proceed();
		System.out.println("环绕-后置");
		return result;
	}
}

配置ApplicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="myaround" class="a.b.advice.MyAround"></bean>
    <aop:config>
    	<aop:pointcut expression="execution(* a.b.test.Demo.demo1())" id="mypoint"/>
        <aop:advisor advice-ref="myaround" pointcut-ref="mypoint"/>
    </aop:config>
    <bean id="demo" class="a.b.test.Demo"></bean>
</beans>

输出结果

以上就是使用Schema-based方式来配置异常和环绕通知

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值