1.创建自定义注解:
import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {
int type();
String msgExpression();
}
@Target参数说明:
参数名称 | 说明 |
TYPE | 类、接口(包括注释类型)或枚举声明 |
FIELD | 字段声明(包括枚举常量) |
METHOD | 方法声明 |
PARAMETER | 参数声明 |
CONSTRUCTOR | 构造方法声明 |
LOCAL_VARIABLE | 局部变量声明 |
ANNOTATION_TYPE | 注释类型声明 |
PACKAGE | 包声明 |
2.创建AOP的切面类 LogAspect:
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
@Aspect
@Component
@RequiredArgsConstructor
public class LogAspect {
final LogOperation logOperation;
/**
* 配置织入点
*/
@Pointcut("@annotation(com.xxx.aop.log.LogAnnotation)")
public void logPointCut() {
}
@Before(value = "logPointCut()")
public void doBefore() {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ra.setAttribute("startTime", System.currentTimeMillis(), 0);
}
/**
* 处理完请求后执行
*
* @param joinPoint 切点
*/
@AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {
logOperation.addOperationLog(joinPoint, jsonResult);
}
/**
* 拦截异常操作
*
* @param joinPoint 切点
* @param e 异常
*/
@AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
logOperation.addOperationLog(joinPoint, e);
}
}
3.写入日志实现类
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
@Component
@RequiredArgsConstructor
public class LogOperation {
final OperationLogService operationLogService;
private static final Logger LOGGER = LoggerFactory.getLogger(LogOperation.class);
/**
* 写入日志
*
* @param joinPoint
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void addOperationLog(JoinPoint joinPoint, Object object) {
// 获得注解
LogAnnotation myLog = getAnnotationLog(joinPoint);
if (myLog == null) {
return;
}
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
// 日志保存
OperationLog log = new OperationLog();
String operationIp = IpUtils.getIP(request);
log.setOperationIp(operationIp);
log.setDuration(System.currentTimeMillis() - (Long) ra.getAttribute("startTime", 0));
log.setCreatedAt(new Date());
log.setLogType(myLog.type());
log.setContent(myLog.msgExpression());
if (null == object) {
log.setRes(Constants.SC_OK);
} else if (object instanceof Exception) {
log.setRes(Constants.SC_ERROR);
log.setErrorMessage(((Exception) object).getMessage());
} else {
ResultResponse res = (ResultResponse) object;
log.setRes(res.getCode().equals(Constants.SC_OK) ? Constants.SC_OK : Constants.SC_ERROR);
log.setErrorMessage(res.getMessage());
}
operationLogService.save(log);
}
/**
* 是否存在注解,如果存在就获取
*/
private LogAnnotation getAnnotationLog(JoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null) {
return method.getAnnotation(LogAnnotation.class);
}
return null;
}
}
4.在需要拦截的方法上加上注解:
@LogAnnotation(type = 0, msgExpression = "xxx")
@Transactional
public ResultResponse test(HttpSession session) {
……
}