package com.base.config;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReflectUtil;
import com.base.framework.utils.assertions.Asserts;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
* @Author : LukeRen
* @DateTime: 2021/12/16 17:49
* @Description :
* @Version : 1.0
*/
@Aspect
@Component
@Slf4j
@AllArgsConstructor
public class SysNoticeAop {
/**
* 切入点
* 通过注解实现切面
* @annotation SysNotice 注解就是一个空注解, 里面什么定义都没有
*/
@Pointcut("@annotation(com.base.config.SysNotice)")
public void sysNoticePointcut() {
}
/**
* 配置环绕通知,使用在方法logPointcut()上注册的切入点
*
* @param joinPoint join point for advice
*/
@Around("sysNoticePointcut()") // 里面的参数是 切入点的方法名
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
//系统通知
Object[] args = joinPoint.getArgs();
String versionIdStr = null;
for (Object arg : args) {
Class<?> aClass = arg.getClass();
String simpleName = aClass.getSimpleName();
//获取请求信息使用RequestFacade, 获取响应信息使用 ResponseFacade
if (!"RequestFacade".equals(simpleName)) {
// 从@RequestBody参数中获取版本id // ReflectUtil.getField 是Hutools的工具类
versionIdStr = Optional.ofNullable(ReflectUtil.getField(aClass, "versionId"))
.map(field -> Convert.toStr(ReflectUtil.getFieldValue(arg, field)))
.orElse(null);
//没有获取到, 从@PathVariable注解中获取
if (null == versionIdStr){
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Map<String, Object> attribute = (Map)request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
versionIdStr = (String)attribute.get("versionId");
System.out.println(attribute);
}
Asserts.isTrue(!StringUtils.isEmpty(versionIdStr), "500", "系统通知内部错误, 参数不存在");
}
}
// 必须有返回对象, 不然controller得响应信息不得返回前端
Object obj = joinPoint.proceed();
return obj;
}
}