赞
踩
承接上一篇AOP前言
本片,我们学习AOP的剩余4种通知的方式。
后置通知,就是在目标方法执行之后执行切面方法
我们依然使用上文种的目标类和切面类
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; /** * 切面类 */ @Aspect public class MyAspect { @AfterReturning(value = "execution(* com.yuyi.serviec.SomeserviceImpl.doSome())" ,returning = "result") public void afterReturning(Object result){ System.out.println("后置通知,在方法执行之后!"); System.out.println("这是从切面得到的结果"+result); } }
在这里我们依然用Aspect表明切面类
在增强的方法上使用@AfterReturning通知标签,表明执行时间,该标签有两种属性,一种是大家熟悉的value属性,表明切入点,另一种是returning 属性,表示可以得到目标方法的执行结果,该result必须和传入增强方法的参数名一致。
目标方法
public class SomeserviceImpl implements Someservice {
@Override
public String doSome() {
System.out.println("someservice的doSome方法!");
return "这是返回结果!";
}
}
我们运行测试类
环绕通知是功能最强的通知,可以在目标方法之前和之后都可以执行。它可以控制目标方法是否执行,也可以修改目标方法的执行结果
切面类
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; /** * 切面类 */ @Aspect public class MyAspect { @Around(value = "execution(* com.yuyi.serviec.SomeserviceImpl.doSome())" ) public Object myAroung(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("目标 方法之前!"); Object result = proceedingJoinPoint.proceed(); System.out.println("目标方法之后!"); return result; } }
在切面类上使用@Around 表示执行时间,使用value表示 切入点的位置,增强方法的参数,其类型为ProceedingJoinPoint,这是一个接口,该接口有proceed方法,可以控制目标函数的执行,从代码种我们可以看出,它继承了JoinPoint的类。即这是与切入点有关的。
package org.aspectj.lang;
import org.aspectj.runtime.internal.AroundClosure;
public interface ProceedingJoinPoint extends JoinPoint {
void set$AroundClosure(AroundClosure var1);
Object proceed() throws Throwable;
Object proceed(Object[] var1) throws Throwable;
}
我们运行测试类
该异常通知是在目标类抛出异常的时候执行,该通知方法不是异常的处理程序,异常还是该抛出抛出,该捕捉捕捉。
我们看一次切面类和方法
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; /** * 切面类 */ @Aspect public class MyAspect { @AfterThrowing(value = "execution(* com.yuyi.serviec.SomeserviceImpl.doSome())" ,throwing = "throwable" ) public void myThrowing(Throwable throwable) { System.out.println("目标方法抛出异常,异常是"+throwable.getMessage()); } }
在上文代码中,我们使用AfterThrowing修饰切面方法,该注解有两个属性,一个是切入点执行位置,一个是抛出的异常,该异常的引用名称必须和下文中方法的形参一致
在目标方法中我们手动设置异常,
public void doSome() {
System.out.println("someservice的doSome方法!");
int a= 10/0;
}
运行测视类
最终通知是一定会执行的通知,不管目标程序是否发生异常,是不是像finally子句。
可以进行资源的回收,内存的释放等工作。
@After(value = "execution(* com.yuyi.serviec.SomeserviceImpl.doSome())"
)
public void myThrowing() {
System.out.println("我是最终通知,可以做资源的回收,内存的释放!");
}
我们进行测试,结果应该是,出错之后,After修饰的类继续执行!
看,和结果一模一样。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。