AOP实践-日志记录

AOP实践-自定义注解实现日志记录
项目环境springboot
spring AOP默认是使用AspectJ的注解 https://www.eclipse.org/aspectj/

1.引入jar包

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2.自定义注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MethodLog {
	String remark() default "";
	
	int operType() default 0;
}

3.日志记录
此处每次操作完成之后记录日志

@Component
@Aspect
public class LogService {
	@Autowired
	OperateLogMapper operateLogMapper;
	
	/**
	 * 切点
	 */
	@Pointcut("@annotation(com.cmft.basic.aspect.annotation.MethodLog)")
	public void methodCachePointcut() {
	}
	
	@AfterThrowing("methodCachePointcut()")
	public void test(JoinPoint point) {
	}
	
	/**
	 * 切面
	 *
	 * @param point
	 * @return
	 * @throws Throwable
	 */
	@AfterReturning("methodCachePointcut()")
	public void recordOperateLog(JoinPoint point) throws Throwable {
		Map<String, Object> methodMap = getMthodMap(point);
		String packages = point.getThis().getClass().getName();
		if (packages.indexOf("$$EnhancerByCGLIB$$") > -1) { // 如果是CGLIB动态生成的类
			packages = packages.substring(0, packages.indexOf("$$"));
			return;
		}
		Object[] methodParam = null;
		methodParam = point.getArgs(); // 获取方法参数
		Map<String, Object> parMap = objectToMap(methodParam[0]);
		// 记录日志
		//...
		operateLog.setRemark(String.valueOf(methodMap.get("remark")));
		operateLog.setTypeId((Integer)methodMap.get("operType"));
		//...
	}
	
	/**
	 * 获取利用反射获取类里面的值和名称
	 *
	 * @param obj
	 * @return
	 * @throws IllegalAccessException
	 */
	public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
		Map<String, Object> map = new HashMap<>();
		Class<?> clazz = obj.getClass();
		if (clazz.isPrimitive() || clazz.getName().equals("java.lang.String")) {
			map.put("id", obj);
			return map;
		}
		for (Field field : clazz.getDeclaredFields()) {
			field.setAccessible(true);
			String fieldName = field.getName();
			Object value = field.get(obj);
			map.put(fieldName, value);
		}
		return map;
	}
	
	/**
	 * 获取方法中的中文备注
	 *
	 * @param joinPoint
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> getMthodMap(JoinPoint joinPoint) throws Exception {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();
		Class<?> targetClass = Class.forName(targetName);
		Method[] method = targetClass.getMethods();
		Map<String, Object> methodMap = new HashMap<String, Object>();
		for (Method m : method) {
			if (m.getName().equals(methodName)) {
				@SuppressWarnings("rawtypes")
				Class[] tmpCs = m.getParameterTypes();
				if (tmpCs.length == arguments.length) {
					MethodLog methodCache = m.getAnnotation(MethodLog.class);
					if (methodCache != null) {
						int operType = methodCache.operType();
						String remark = methodCache.remark();
						methodMap.put("operType", operType);
						methodMap.put("remark", remark);
					}
					break;
				}
			}
		}
		return methodMap;
	}
}

4.使用
AOP必须基于接口实现,所以在接口实现类的方法上加入如下注解即可

@MethodLog(remark = "更新", operType = Constant.APPROVE)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值