Spring4_08_AOP通知
spring aop通知(advice)分成五类:
前置通知[Before advice]:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常。
后置通知[After returning advice]:在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行。
异常返回通知[After throwing advice]:在连接点抛出异常后执行。
返回通知[After (finally) advice]:在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容。
环绕通知[Around advice]:环绕通知围绕在连接点前后,比如一个方法调用的前后。这是最强大的通知类型,能在方法调用前后自定义一些操作。环绕通知还需要负责决定是继续处理join point(调用ProceedingJoinPoint的proceed方法)还是中断执行。利用上一篇的模拟学生添加过程,来测试这几种通知:
需要引入的东西
- jar包:
添加到对应lib,然后add bulid path
2.引入方式:
引入路径和xsd文件
前置通知
在执行前需要进行的操作, 在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常
新建一个包advice专门写通知,在包里新建studentserviceAspect文件
写一个doBefore方法:
public void doBefore(JoinPoint jp) {
System.out.println("开始添加学生:"+jp.getArgs()[0]);
}
在beans.xml中配置:
<aop:config>
<aop:aspect id="studentServiceAspect" ref="studentServiceAspect">
<aop:pointcut expression="execution(* com.java.studentservice.*.*(..))"
id="businessService"/>
<aop:before method="doBefore" pointcut-ref="businessService"/>
</aop:aspect>
</aop:config>
执行:
@Test
public void test1() {
StudentService studentservice = (StudentService)ac.getBean("studentservice");
studentservice.addStudent("张三");
}
也可以在doBefore中返回类名,方法名 ,参数
public void doBefore(JoinPoint jp) {
System.out.println("类名:"+jp.getTarget().getClass().getName());
System.out.println("方法名:"+jp.getSignature().getName());
System.out.println("开始添加学生:"+jp.getArgs()[0]);
}
执行后:
后置通知
在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行。
在StudentServiceAspect类中定义doAfter方法;
public void doAfter(JoinPoint jp) {
System.out.println("类名:"+jp.getTarget().getClass().getName());
System.out.println("方法名:"+jp.getSignature().getName());
System.out.println("添加学生完成:"+jp.getArgs()[0]);
}
配置与前置通知一样:
<aop:after method="doAfter" pointcut-ref="businessService"/>
执行:
环绕通知
环绕通知围绕在连接点前后,比如一个方法调用的前后。这是最强大的通知类型,能在方法调用前后自定义一些操作。环绕通知还需要负责决定是继续处理join point(调用ProceedingJoinPoint的proceed方法)还是中断执行。
在StudentServiceAspect类中定义doAround方法;
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("添加学生前");
Object retValue = pjp.proceed();
System.out.println("返回值:"+retValue);
System.out.println("添加学生后");
return retValue;
}
<aop:around method="doAround" pointcut-ref="businessService"/>
执行;
优先级比前置与后置要高。
返回值对应方法的返回值(此时方法返回值为void)
返回通知
在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容。
在StudentServiceAspect类中定义doAfterReturning方法;
public void doAfterReturning(JoinPoint jp) {
System.out.println("返回通知");
}
配置:
<aop:after-returning method="doAfterReturning" pointcut-ref="businessService"/>
执行:
异常通知
在连接点抛出异常后执行。
在StudentServiceAspect类中定义doAfterThrowing方法;
public void doAfterThrowing(JoinPoint jp,Throwable ex) {
System.out.println("异常通知");
System.out.println("异常信息:"+ex.getMessage());
}
在impl实现中,写一个异常:
@Override
public void addStudent(String name) {
//System.out.println("开始添加学生");
System.out.println("添加学生:"+name);
System.out.println(1/0);
//System.out.println("学生"+name+"添加完成");
}
0不能为分母
在beans.xml中配置:
<aop:after-throwing method="doAfterThrowing" throwing="ex" pointcut-ref="businessService"/>
执行: