AOP概念及使用(2)其余4中通知的实现方式。
承接上一篇AOP前言
本片,我们学习AOP的剩余4种通知的方式。
1.后置通知
后置通知,就是在目标方法执行之后执行切面方法
我们依然使用上文种的目标类和切面类
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;
}
我们运行测试类
3.异常通知
该异常通知是在目标类抛出异常的时候执行,该通知方法不是异常的处理程序,异常还是该抛出抛出,该捕捉捕捉。
我们看一次切面类和方法
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;
}
运行测视类
4.最终通知
最终通知是一定会执行的通知,不管目标程序是否发生异常,是不是像finally子句。
可以进行资源的回收,内存的释放等工作。
@After(value = "execution(* com.yuyi.serviec.SomeserviceImpl.doSome())"
)
public void myThrowing() {
System.out.println("我是最终通知,可以做资源的回收,内存的释放!");
}
我们进行测试,结果应该是,出错之后,After修饰的类继续执行!
看,和结果一模一样。