@Aspect
@Component
public class LoggingAspect {
/**
* 在 com.spring.aop.Impl.ArithmeticCalculator 接口的每一个实现类的每一个方法开始之前执行一段代码.
*/
@Before("execution(* com.spring.aop.Impl.*.*(..))")
public void beforeMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("The Method " + methodName + " begins with " + Arrays.asList(args));
}
/**
* 在方法执行之后执行的代码. 无论该方法是否出现异常
*/
@After("execution(* com.spring.aop.Impl.*.*(..))")
public void afterMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println("The Method " + methodName + " ends");
}
/**
* 在方法正常结束后执行的代码
* 返回通知是可以访问到方法的返回值的
*/
//返回通知
@AfterReturning(value="execution(* com.spring.aop.Impl.*.*(..))",returning="result")
public void afterReturning(JoinPoint joinPoint,Object result){
String methodName = joinPoint.getSignature().getName();
System.out.println("The Method " + methodName + " ends with " + result);
}
/**
* 在目标方法出现异常时, 会执行的代码.
* 可以访问到异常对象, 且可以指定再出现特定异常时再执行通知代码
*/
@AfterThrowing(value="execution(* com.spring.aop.Impl.*.*(..))", throwing="ex")
public void afterThrowing(JoinPoint joinPoint, Exception ex){
String methodName = joinPoint.getSignature().getName();
System.out.println("The Method " + methodName + " occurs excetion: " + ex);
}
/**
* 环绕通知需要携带 ProceedingJoinPoint 类型的参数.
* 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是否执行目标方法
* 且环绕通知必须有返回值, 返回值即为目标方法的返回值.
*/
@Around("execution(* com.spring.aop.Impl.*.*(..))")
public Object aroundMethod(ProceedingJoinPoint joinPoint){
Object result = null;
String methodName = joinPoint.getSignature().getName();
//执行目标方法
try {
//前置通知
System.out.println("The method " + methodName + " begins with " + Arrays.asList(joinPoint.getArgs()));
//执行目标方法
result = joinPoint.proceed();
//后置通知
System.out.println("The method " + methodName + " ends with " + result);
} catch (Throwable e) {
//异常通知
System.out.println("The method " + methodName + " occurs exception: " + e);
throw new RuntimeException(e);
}
//后置通知
System.out.println("The method " + methodName + " ends");
return result;
}
}
package com.abc.advice;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
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 AdviceTest {
@Around("execution(* com.abc.service.*.many*(..))")
public Object process(ProceedingJoinPoint point) throws Throwable {
System.out.println("@Around:执行目标方法之前...");
Object[] args = point.getArgs();
if (args != null && args.length > 0 && args[0].getClass() == String.class) {
args[0] = "改变后的参数1";
}
Object returnValue = point.proceed(args);
System.out.println("@Around:执行目标方法之后...");
System.out.println("@Around:被织入的目标对象为:" + point.getTarget());
return "原返回值:" + returnValue + ",这是返回结果的后缀";
}
@Before("execution(* com.abc.service.*.many*(..))")
public void permissionCheck(JoinPoint point) {
System.out.println("@Before:模拟权限检查...");
System.out.println("@Before:目标方法为:" +
point.getSignature().getDeclaringTypeName() +
"." + point.getSignature().getName());
System.out.println("@Before:参数为:" + Arrays.toString(point.getArgs()));
System.out.println("@Before:被织入的目标对象为:" + point.getTarget());
}
@AfterReturning(pointcut="execution(* com.abc.service.*.many*(..))",
returning="returnValue")
public void log(JoinPoint point, Object returnValue) {
System.out.println("@AfterReturning:模拟日志记录功能...");
System.out.println("@AfterReturning:目标方法为:" +
point.getSignature().getDeclaringTypeName() +
"." + point.getSignature().getName());
System.out.println("@AfterReturning:参数为:" +
Arrays.toString(point.getArgs()));
System.out.println("@AfterReturning:返回值为:" + returnValue);
System.out.println("@AfterReturning:被织入的目标对象为:" + point.getTarget());
}
@After("execution(* com.abc.service.*.many*(..))")
public void releaseResource(JoinPoint point) {
System.out.println("@After:模拟释放资源...");
System.out.println("@After:目标方法为:" +
point.getSignature().getDeclaringTypeName() +
"." + point.getSignature().getName());
System.out.println("@After:参数为:" + Arrays.toString(point.getArgs()));
System.out.println("@After:被织入的目标对象为:" + point.getTarget());
}
}