简介
@Around环绕通知:它集成了@Before、@AfterReturing、@AfterThrowing、@After四大通知。需要注意的是,他和其他四大通知注解最大的不同是需要手动进行接口内方法的反射后才能执行接口中的方法,换言之,@Around其实就是一个动态代理。
具体写法
package com.atguigu.utils;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
//@Aspect:给spring说明这个组件是切面类
/*
* try{
* @Before
* Result = method.invoke(obj,args);
* @AfterReturing
* }catch(e){
* @AfterReturing
* }finally{
* @After
* }
* */
/*
* 五个注解:
* @Before:在目标方法之前运行; 前置通知
* @After:在目标方法结束之后运行; 后置通知
* @AfterReturing:在目标方法正常返回之后; 返回通知
* @AfterThrowing:在目标方法抛出异常之后运行; 异常通知
* @Around:环绕 环绕通知
* */
@Aspect
@Component
public class LogUtils {
@Pointcut("execution(public int com.atguigu.impl.MyMathCalculator.*(int, int))")
public void myPoint(){}
@Around(value = "myPoint()")
public Object myAround(ProceedingJoinPoint pjp) throws Throwable{
Object[] args = pjp.getArgs();
String name = pjp.getSignature().getName();
Object proceed=null;
try {
//@Before
System.out.println("【环绕前置通知】【"+name+"方法开始】");
/*这句相当于method.invoke(obj,args),通过反射来执行接口中的方法;因此在反射执行完方法后会有一个返回值proceed*/
proceed = pjp.proceed();
//@AfterReturning
System.out.println("【环绕返回通知】【"+name+"方法返回,返回值:"+proceed+"】");
} catch (Exception e) {
//@AfterThrowing
System.out.println("【环绕异常通知】【"+name+"方法异常,异常信息:"+e+"】");
}finally{
//@After
System.out.println("【环绕后置通知】【"+name+"方法结束】");
}
return proceed;
}
}
注意:myAround(ProceedingJoinPoint pjp)的内部参数部分ProceedingJoinPoint pjp,pjp中包含了接口中方法的信息,可通过pjp.的方式获取接口方法信息(如方法名,方法内参数,返回值等信息)。