1.首先自定义一个注解
package com.example.demo.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
@Target({METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedLog {
String value() default "";
}
2.编写aop切面
package com.example.demo.config;
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.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.HashSet;
@Component //把当前类注入到spring容器中
@Aspect //把当前类标识为一个切面供容器读取
@Slf4j
public class AopConfig {
private static final Logger log = LoggerFactory.getLogger(AopConfig.class);
/**
* 指定切入点
* 使用自定义注解@NeedLog 的方法,进行切面
*/
@Pointcut("@annotation(com.example.demo.annotation.NeedLog)")
private void useMethod() {
}
@Around(value = "useMethod()")
public Object recordLog(ProceedingJoinPoint proceedingJoinPoint) {
log.info("=====开始=====");
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
assert requestAttributes != null;
HttpServletRequest request = requestAttributes.getRequest();
String uri = request.getRequestURI();
String method = request.getMethod();
//nginx代理 request.getHeader("X-Real-IP")
log.info("请求ip... " + request.getRemoteAddr());
log.info("请求路径... " + uri);
log.info("请求方式... " + method);
MethodSignature targetMethod = (MethodSignature) proceedingJoinPoint.getSignature();
log.info("请求方法... " + targetMethod.toString());
Object[] args = proceedingJoinPoint.getArgs();
HashSet<String> set = new HashSet<>();
for (Object o : args) {
set.add(String.valueOf(o));
}
log.info("请求参数... " + set);
Object object;
try {
object = proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
//控制台打印
throwable.printStackTrace();
//日志打印详细异常信息
log.info("服务异常 {}",throwable.getMessage(),throwable);
//controller层统一异常处理
return "error";
}
log.info("返回参数... " + object);
log.info("=====结束=====");
return object;
}
}
3.应用效果
package com.example.demo.controller;
import com.example.demo.annotation.NeedLog;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@GetMapping("test")
@NeedLog
public String test(@RequestParam(value = "param") String param, @RequestParam(value = "nice") String nice) {
return "controller层aop切面日志";
}
}