1、前言
开发过程中我们往往需要写许多打印请求参数以及返回参数的代码,而这些操作存在于每个方法之中,使得我们代码较为冗余,为此我们可以通过动态代理将打印参数和打印返回报文作为切面,使用切入点表达式将其切入至每个方法之中。
2、应用场景
1)方法出入参打印
2)事物控制
3)全局异常处理
3、代码
在 springboot 的启动类上,添加注解
@ComponentScan({ "com.fbank.dis_product_service"}),扫描包下的所有注解。
@EnableAspectJAutoProxy(proxyTargetClass=true),开启AOP代理自动配置。
import com.fbank.dis_common.consts.enums.DisMsg;
import com.fbank.fast.core.exception.AppException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.Map;
@Aspect
@Component
public class SleepHelper {
/**
* 切点表达式:dubbo开头的方法名,都会打印入参出参
*/
@Pointcut("execution(* com.fbank.dis_product_service.web.*.dubbo*(..))")
public void pointCut(){
}
/**
* 前置通知
*/
@Before("pointCut()")
public void before(JoinPoint point){
Object[] args = point.getArgs();
System.out.println("接收的请求报文:"+ Arrays.toString(args));
}
/**
* 环绕通知
* ProceedingJoinPoint :只能用在“环绕通知”
*/
@Around("pointCut()")
public Object process(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//横切的类
Signature signature = proceedingJoinPoint.getSignature();
String className = signature.getDeclaringTypeName();
//横切的方法
String methodName = signature.getName();
//请求参数
Object[] args = proceedingJoinPoint.getArgs();
logger.info("开始请求:接口类=[{}], 方法=[{}], 请求参数=[{}]", className, methodName, JSONObject.toJSONString(args));
long start = System.currentTimeMillis();
//执行切点,并返回结果
Object result = proceedingJoinPoint.proceed();
long end = System.currentTimeMillis();
logger.info("响应结果=[{}], 执行时间=[{}ms]", JSONObject.toJSONString(result), end - start);
//注意要返回执行结果,否则结果就丢失了
return result;
}
/**
* 后置通知
*/
@AfterReturning("pointCut()")
public void afterReturing(JoinPoint joinPoint) {
}
/**
* 最终通知
*/
@After("pointCut()")
public void after(JoinPoint joinPoint) {
}
/**
* 异常通知
*/
@AfterThrowing(throwing = "ex", pointcut = "pointCut()")
public void handleSleep(Exception ex) {
ex.printStackTrace();
if (ex instanceof Exception) {
throw new AppException(DisMsg.COMMUNICATE_ERR);
}
}
}