NO.12 Spring AOP 通知
通知: 拦截到连接点后,所要做的事情就是通知 。
通知的分类:
1、前置通知
2、后置通知
3、后置返回通知
4、环绕通知<前置通知和后置通知结合在一起>
5、异常通知
这里我们依次介绍Spring AOP中的这几类通知。
1.前置通知
2.后置通知
两者类似:
配置文件:
<?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:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="stuCardService" class="com.xt.spring.aop.xml.StuCardServiceImpl"></bean>
<!-- 配置通知类 -->
<bean id="loggerAspect" class="com.xt.spring.aop.xml.LoggerAspect"></bean>
<aop:config>
<!-- 拦截类里的一个方法 -->
<aop:pointcut expression="execution(String com.xt.spring.aop.xml.StuCardServiceImpl.deposit(..))" id="stuCardDeposit"/>
<aop:aspect ref="loggerAspect">
<aop:before method="beforeMethodAdvice" pointcut-ref="stuCardDeposit"/>
</aop:aspect>
</aop:config>
</beans>
通知类:
package com.xt.spring.aop.xml;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class LoggerAspect {
//自定义前置通知
public void beforeMethodAdvice(JoinPoint jp){
System.out.println("方法:"+ jp.getSignature().getName() + "被执行,前置通知被触发.......");
Object[] args = jp.getArgs();
}
//自定义后置通知
public void afterMethodAdvice(JoinPoint jp){
System.out.println("方法:"+ jp.getSignature().getName() + "被执行,后置通知被触发.......");
}
}
3.后置返回通知
配置文件:
<!-- 后置返回通知 方法参数返回值名字需与returning返回值名字相同-->
<aop:after-returning method="afterReturningMethodAdvice" pointcut-ref="stuCardDeposit" returning="result"/>
自定义后置返回通知:
public void afterReturningMethodAdvice(JoinPoint jp,Object result){
System.out.println("方法:"+ jp.getSignature().getName() + "被执行,后置返回通知被触发,返回值为" + result);
}
4.环绕通知
配置文件:
<aop:around method="aroundMethodAdvice" pointcut-ref="stuCardDeposit"/>
自定义环绕通知:
//ProceedingJoinPoint接口继承JoinPoint接口,它新增了用于执行连接点的方法proceed
//环绕方法的返回值需要与拦截的方法的返回值相同
public Object aroundMethodAdvice(ProceedingJoinPoint pjp){
System.out.println("方法:"+ pjp.getSignature().getName() + "被执行,环绕通知前置日志打印***********");
//目标方法的擦描述
Object[] args = pjp.getArgs();
//可以改变参数值
args[1] = "神通广大";
Object returnValue = null;
try {
returnValue = pjp.proceed(args);
//proceed相当于方法invoke,代理业务执行,而自定义的方法可以抛出任何类型异常,故而为Throwable
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("方法:"+ pjp.getSignature().getName() + "被执行,环绕通知后置日志打印,返回结果" +returnValue);
return returnValue;
}
5.异常通知
配置文件:
<aop:after-throwing method="afterThrowingAdvice" pointcut-ref="stuCardDeposit" throwing="e"/>
自定义异常通知:
public void afterThrowingAdvice(JoinPoint jp, Exception e){
System.out.println("后置异常通知:方法:" + jp.getSignature().getName() + "抛出异常" + e);
}
StuCardServiceImpl实现类:
package com.xt.spring.aop.xml;
public class StuCardServiceImpl implements StuCardService{
public String deposit(String cardNo, String money) {
System.out.println("向学生卡" + cardNo + "存钱:" + money);
if("神通广大".equals(money)){
//if(money.equals("神通广大")){可能会出现空指针
throw new RuntimeException("不能再存钱了,卡已被存爆了。。。。");
}
return money;
}
}