java通过AOP实现全局日志打印详解

网友投稿 733 2022-09-03


java通过AOP实现全局日志打印详解

目录几个常用的切点注解,这次使用了@Before和@Around切Controller打印请求的接口、参数、返回值以及耗时情况。切Service打印日志,URL,请求方式,IP,类名,方法总结

几个常用的切点注解,这次使用了@Before和@Around

1.@Before 前置增强(目标方法执行之前,执行注解标注的内容)

2.@AfterReturning 后置增强(目标方法正常执行完毕后,执行)

3.@Around 环绕增强(目标方法执行前后,分别执行一些代码)

4.@AfterThrowing 抛出增强(目标方法发生异常,执行)

5.@After Final增强(不管是抛出异常还是正常退出,该增强都会得到执行。一般用于释放资源,相当于try{}finally{})。

切Controller打印请求的接口、参数、返回值以及耗时情况。

package com.tfjy.arbackend.aop;

import com.alibaba.fastjson.JSONObject;

import com.tfjy.arbackend.util.FrontResult;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

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.web.context.request.RequestContextHolder;

import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.util.ArrayList;

import java.util.List;

/**

* 使用AOP切Controller打印日志

*

* @author Promsing(张有博)

* @version 1.0.0

* @since 2021/12/5 - 21:09

*/

@Aspect

@Component

public class RestAopConfig {

/**

* 控制是否开启日志

*/

public static Boolean onOff = false;

private static Log logger = LogFactory.getLog(RestAopConfig.class);

@Pointcut("execution(public * com.tfjy.arbackend.controllerhttp://..*.*(..))")

public void pointCutRestDef(){

}

//环绕切点

@Around("pointCutRestDef()")

public Object processRst(ProceedingJoinPoint point) throws Throwable{

Object returnValue = null;

final List params = new ArrayList<>();

//获得请求信息

ServletRequestAttributes sra =(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();

if(sra==null){

return point.proceed();

}

HttpServletRequest request = sra.getRequest();

Object[] args = point.getArgs();

//过滤出HttpServlet

for (int i = 0; i < args.length; i++) {

Object object = args[i];

if (object instanceof HttpServletResponse){

continue;

}

if (object instanceof HttpServletRequest){

continue;

}

params.add(object);

}

logger.info(

"rest method:——>"+point.getSignature().getDeclaringTypeName()+"."+point.getSignature().getName());

String cloneParams = JSONObject.toJSONString(params);

logger.info("rest param:——>"+cloneParams);

long startTime = System.currentTimeMillis();

//去执行方法,这里的异常交给统一捕获异常去处理

returnValue = point.proceed(point.getArgs());

//处理返回值

if (returnValue instanceof FrontResult){

FrontResult frontResult=(FrontResult)returnValue;

logger.info("rest response:——>"+frontResult.toString());

}

long endTime = System.currentTimeMillis();

logger.info("rest"+request.getRequestURI()+"----used time----"+(endTime - startTime));

Boolean boolean1 =true;

if (returnValue != null && !returnValue.equals(boolean1)){

logger.info(JSONObject.toJSONString(returnValue));

}

return returnValue;

}

}

切Service打印日志,URL,请求方式,IP,类名,方法

package com.tfjy.arbackend.aop;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.Pointcut;

import org.springframework.stereotype.Component;

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.util.Arrays;

/**

* 使用AOP切Service打印日志

*

* @author Promsing(张有博)

* @version 1.0.0

* @since 2021/12/5 - 21:09

*/

@Aspect //注解将一个java类定义为切面类

@Component

public class AopGetService {

private static Log logger = LogFactory.getLog(AopGetService.class);

/*使用@Pointcut定义一个切入点,可以是一个规则表达式,比如下例中某个package下的所有函数,也可以是一个注解等。

根据需要在切入点不同位置的切入内容*/

@Pointcut("execution(public * com.tfjy.arbackend.service..*.*(..))")//切入点描述 这个是service包的切入点

public void getServiceJournal() {

}//签名,可以理解成这个切入点的一个名称

//前置切点

@Before("getServiceJournal()")//在切入点开始处切入内容

public void logBeforeService(JoinPoint joinPoint) {

// 接收到请求,记录请求内容

RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

if(requestAttributes==null){

return ;

}

HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();

// 记录下请求内容

logger.info("URL : " + request.getRequestURL().toString());

logger.info("HTTP_METHOD : " + request.getMethod());

logger.info("IP : " + request.getRemoteAddr());

//下面这个getSignature().getDeclaringTypeName()是获取包+类名的 然后后面的joinPoint.getSignature.getName()获取了方法名

logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());

logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));

}

}

总结


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Django 源码的学习(一)
下一篇:python爬虫爬取下厨房食谱,周末聚餐真的停不下来
相关文章

 发表评论

暂时没有评论,来抢沙发吧~