使用AOP3.2.4 @annotation表达式方式为日志增添添加功能

1 篇文章 0 订阅
本文介绍了如何使用AOP(面向切面编程)和自定义注解在Spring框架中实现细粒度的日志管理。通过定义`@RequiredLog`注解,可以在业务方法上标记需要记录日志的逻辑。当方法被调用时,切面会自动捕获并处理日志,包括记录执行时间、操作信息、IP地址、用户名、方法信息及参数等。这种做法提高了代码的可维护性和解耦性。
摘要由CSDN通过智能技术生成

说明
@annotaion表达式应用于方法级别,实现细粒度的切入点表达式定义
▪ @annotation(anno.RequiredLog) 匹配有此注解描述的方法。
▪ @annotation(anno.RequiredCache) 匹配有此注解描述的方法。
其中:RequiredLog为我们自己定义的注解,当我们使用@RequiredLog注解修饰业务层方法时,系统底层会在执行此方法时进行日扩展操作。

1 前期配置见AOP文章
2:定义注解
例如

package com.cy.pj.sys.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiredLog {
	String value() default "operation";
}

3:定义切面对象
例:

import com.cy.pj.sys.entity.SysLog;
import com.cy.pj.sys.service.SysLogService;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Aspect
@Component
public class SysLogAspect {
	@Pointcut("@annotation(包名.注解定义类名)")
	public void doCache() {} //方法中不写任何内容,只是切入点表达式

	@Around("doCache()")
	public Object around(ProceedingJoinPoint jp) throws Throwable{
		......
		要增强的内容
		......
		return result;
		} catch (Throwable e) {
			// TODO: handle exception
			log.error("目标方法在执行过程中出现了问题,具体问题是:{}",e.getMessage());
			throw e;
		}		
	}

例如:

package com.cy.pj.sys.acpect;

import java.lang.reflect.Method;
import java.util.Date;

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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.cy.pj.common.vo.IPUtils;
import com.cy.pj.sys.annotation.RequiredLog;
import com.cy.pj.sys.entity.SysLog;
import com.cy.pj.sys.service.SysLogService;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Aspect
@Component
public class SysLogAspect {
	
	@Pointcut("@annotation(com.cy.pj.sys.annotation.RequiredLog)")
	public void doCache() {}
	
	@Around("doCache()")
	public Object around(ProceedingJoinPoint jp) throws Throwable{
		long start = System.currentTimeMillis();
		try {
			Object result = jp.proceed();
		long end = System.currentTimeMillis();
		long time = end-start;
		System.out.println("111111111");
		saveUserLog(jp,time);
		return result;
		
		} catch (Throwable e) {
			// TODO: handle exception
			log.error("目标方法在执行过程中出现了问题,具体问题是:{}",e.getMessage());
			throw e;
		}
			
	}
	
	@Autowired
	private SysLogService sysLogService;
	private void saveUserLog(ProceedingJoinPoint jp,long time) throws Throwable{
		//1 获取用户行为日志
		//1.1 获取ip地址
		String ipAddr = IPUtils.getIpAddr();
		//1.2 获取登录用户名
		String username = "jihaolong";
		//1.3 获取操作名
		Class<?> targetClass = jp.getTarget().getClass();
		MethodSignature ms = (MethodSignature)jp.getSignature();
		String methodName = ms.getName();
		Method targetMethod = targetClass.getMethod(methodName, ms.getParameterTypes());
		RequiredLog requiredLog = targetMethod.getAnnotation(RequiredLog.class);
		String operation = "operation";
		if(requiredLog!=null) {
			operation=requiredLog.value();
		}
		//1.4 获取目标方法信息(类全名+方法名)
		String method = targetClass.getName()+"."+methodName;
		//1.5 获取方法执行时传入的实际参数
		//String params = Arrays.toString(jp.getArgs());// 转普通串
		String params = new ObjectMapper().writeValueAsString(jp.getArgs());// 将实际参数转成Jason格式的字符串
		// 2. 封装用户行为日志
		SysLog user = new SysLog();
		user.setCreatedTime(new Date());
		user.setIp(ipAddr);
		user.setMethod(method);
		user.setOperation(operation);
		user.setParams(params);
		user.setTime(time);
		user.setUsername(username);
		user.setOperation(operation);
		sysLogService.saveObject(user);
		// 添加线程
//		new Thread() {
//			public void run() {
//				sysLogService.saveObject(user);
//			};
//		}.start();
	}
}

4:在需要添加动态功能的方法上加注解
在这里插入图片描述
5:完成

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值