在记录系统调用日志时,可以使用 @Pointcut("execution(* com.service.mycontroller.controller.*.*(..))")
指定拦截某些类或方法。但是在调用第三方系统时,调用代码可能分布在各个层不同的类和方法中,没办法使用execution表达式精确定位。此时可以自定义一个注解,在使用的方法上添加该注解即可拦截记录日志(像@Transaction一样)。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface SaveLog {
//调用系统枚举类
RequestType value();
//不使用枚举类
//String systemName() default "";
//String operation() default "";
//String url() default "";
}
/**
* @Author shallWe
* @Date 2023-10-09 11:23
*/
public enum RequestType {
SYSTEM1_ADDUSER("system1","addUser"),
SYSTEM1_UPDATEUSER("system1","updateUser"),
SYSTEM1_DELETEUSER("system1","deleteUser"),
SYSTEM2_ADD("system2","add"),
SYSTEM2_UPDATE("system2","update"),
SYSTEM2_DELETE("system2","delete");
private String systemName;
private String operation;
public String getType() {
return systemName;
}
public String getUrl() {
return operation;
}
RequestType(String systemName, String operation) {
this.systemName = systemName;
this.operation = operation;
}
}
/**
* @Author shallWe
* @Date 2023-10-09 11:45
*/
@Component
@Aspect
public class SouthRequestLogAspect {
@Pointcut("@annotation(com.service.common.SaveLog)")
public void requestLog() {
}
@AfterReturning(returning="retObj", pointcut = "requestLog()")
public void doAfterReturning(JoinPoint joinPoint, Object retObj){
//获取系统名称和操作类型
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
SaveLog saveLog = signature.getMethod().getAnnotation(SaveLog.class);
if (saveLog != null) {
System.out.println(saveLog.value().getSystemName());
System.out.println(saveLog.value().getOperation());
}
// 这里只是一个示例,你可以写任何处理逻辑
System.out.println("---------Before触发了----------");
// 获取签名
Signature signature = joinPoint.getSignature();
// 获取切入的包名
String declaringTypeName = signature.getDeclaringTypeName();
// 获取即将执行的方法名
String funcName = signature.getName();
log.info("即将执行方法为: {},属于{}包", funcName, declaringTypeName);
// 也可以用来记录一些信息,比如获取请求的 URL 和 IP
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 获取请求 URL
String url = request.getRequestURL().toString();
// 获取请求 IP
String ip = request.getRemoteAddr();
log.info("用户请求的url为:{},ip地址为:{}", url, ip);
//获取请求的类名
String className = joinPoint.getTarget().getClass().getName();
//获取请求的方法名
String methodName = method.getName();
//请求的参数
Object[] args = joinPoint.getArgs();
//将参数所在的数组转换成json
String params = JsonUtil.getStringFromArray(args);
}
}
此时便可以在任何方法上使用@SaveLog
进行拦截处理了
@SaveLog(RequestType.SYSTEM1_ADDUSER)
public void system1Add(){
System.out.println("调用A系统");
}
@SaveLog(RequestType.SYSTEM2_ADDUSER)
public void systemAdd(){
System.out.println("调用B系统");
}
//不使用枚举类
//@SaveLog(systemName = "A系统", operation = "add", url = "/123/123")
//public void system1Add(){
// System.out.println("调用A系统");
//}
//@SaveLog(systemName = "B系统", operation = "delete", url = "/123/123")
//public void systemAdd(){
// System.out.println("调用B系统");
//}
更多AOP信息:Spring AOP 详解