首先我们需要在项目中引入maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
引人入依赖后为我们就可以开始编写日志切面功能
1、编写方法功能名称注解(在打印日志时知道该方法实现的具体功能)
/**
* @Title: LogRemark
* @Description: 日志中功能备注
* @author: jack
* @date 2019年9月27日 上午8:34:40
*/
@Component
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogRemark {
public String value();
}
2、获取IP地址工具类
public class IpUtil {
private static final String UNKNOWN = "unknown";
private static final String LOCALHOST = "127.0.0.1";
private static final String SEPARATOR = ",";
public static String getIpAddr(HttpServletRequest request) {
System.out.println(request);
String ipAddress;
try {
ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (LOCALHOST.equals(ipAddress)||"0:0:0:0:0:0:0:1".equals(ipAddress)) {
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress = inet.getHostAddress();
}
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
// "***.***.***.***".length()
if (ipAddress != null && ipAddress.length() > 15) {
if (ipAddress.indexOf(SEPARATOR) > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
} catch (Exception e) {
ipAddress = "";
}
return ipAddress;
}
}
3、编写日志切面操作:
@Aspect
@Configuration
@Slf4j
public class LogAopAspect {
// 存储请求开始时间
private ThreadLocal<Long> startTime = new ThreadLocal<>();
@Pointcut("execution(* com.hongyu.web.*.*(..))")
public void webLog() {
}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) {
// 设置请求开始时间
startTime.set(System.currentTimeMillis());
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
MethodSignature signature= (MethodSignature) joinPoint.getSignature();
//获取方法上面对应的接口实现功能名称注解
String remark="";
LogRemark annotation=null;
if(signature.getMethod().getAnnotation(LogRemark.class)!=null) {
annotation=signature.getMethod().getAnnotation(LogRemark.class);
remark=remark+annotation.value()==null?"":annotation.value();
}
log.info(remark+"请求的URL : " + request.getRequestURL().toString());
log.info(remark+"请求方式 : " + request.getMethod());
//获取IP地址
String ipAddr = IpUtil.getIpAddr(request);
log.info(remark+"请求IP地址 : " + ipAddr);
log.info(remark+"请求相关的类和方法名 : " + signature.getDeclaringTypeName() + "."
+ signature.getName());
log.info(remark+"请求参数 : " + JSON.toJSONString(joinPoint.getArgs()));
}
@AfterReturning(value = "webLog()", returning = "ret")
public void doAferReturning(Object ret) {
log.info("本次请求耗时 : " + (System.currentTimeMillis() - startTime.get())/1000);
//log.info("本次请求返回参数: " + JSON.toJSONString(ret));
}
}
4、接口示例:
@LogRemark(value = "查询办理月卡列表")
@PostMapping("/queryList")
public Object selectALLList(@RequestBody MonthPackagesHandle handle) {
if(StringUtils.isEmpty(handle.getHandleId())) {
throw new PromptException(10025, "办理编号不能为空");
}
Iterable<MonthPackagesHandle> findAll = monthHandleRepository.findAll();
return JSONObject.toJSONString(findAll);
}
5、控制台输出示例
到此AOP实现日志输出完成