定义切面和切入点方法,使用注解的方式
@Pointcut("@annotation(com.cy.pj.common.annotation.RequiredLog)") //@annotstion内定义自定义注解使用的位置
@Aspect
@Component
public class SysLogAspect {
private Logger log=LoggerFactory.getLogger(SysLogAspect.class);
@Autowired
private SysLogService sysLogService;
@Pointcut("@annotation(com.cy.pj.common.annotation.RequiredLog)")
public void logPointCut(){}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint //连接点
jointPoint) throws Throwable{
long startTime=System.currentTimeMillis();
//执行目标方法(result 为目标方法的执行结果)
Object result=jointPoint.proceed();
long endTime=System.currentTimeMillis();
long totalTime=endTime-startTime;
log.info("方法执行的总时长为:"+totalTime);
定义方法传入切入点参数和方法执行耗时时间
saveSysLog(jointPoint,totalTime);
return result;
}
定义方法进行日志记录
private void saveSysLog(ProceedingJoinPoint point,
long totleTime) throws NoSuchMethodException,
SecurityException, JsonProcessingException{
//1.获取日志信息
MethodSignature ms= (MethodSignature)point.getSignature();
Class<?> targetClass=point.getTarget().getClass();
String className=targetClass.getName();
//获取接口声明的方法
String methodName=ms.getMethod().getName();
Class<?>[]
parameterTypes=ms.getMethod().getParameterTypes();
//获取目标对象方法(AOP 版本不同,可能获取方法对象方式也不同)
Method targetMethod=targetClass.getDeclaredMethod(
methodName,parameterTypes);
//获取用户名,学完 shiro 再进行自定义实现,没有就先给固定值
String username=ShiroUtils.getPrincipal().getUsername();
//获取方法参数
Object[] paramsObj=point.getArgs();
System.out.println("paramsObj="+paramsObj);
//将参数转换为字符串
String params=new ObjectMapper()
.writeValueAsString(paramsObj);
//2.封装日志信息
SysLog log=new SysLog();
log.setUsername(username);//登陆的用户
//假如目标方法对象上有注解,我们获取注解定义的操作值
RequiredLog requestLog=
targetMethod.getDeclaredAnnotation(RequiredLog.class);
if(requestLog!=null){
log.setOperation(requestLog.value());
}
log.setMethod(className+"."+methodName);//className.methodName()
log.setParams(params);//method params
log.setIp(IPUtils.getIpAddr());//ip 地址
log.setTime(totleTime);//
log.setCreateDate(new Date());
//3.保存日志信息
sysLogService.saveObject(log);
}