AOP实现日志切面

AOP叫做面向切面编程,他是一个编程范式,目的就是提高代码的模块性。SpringAOP基于动态
代理的方式实现,如果是实现了接口的话就会使用JDK动态代理,反之则使用CGLIB代理
Spring中AOP的应用主要体现在事务、日志、异常处理等方面,通过在代码的前后做一些增强处
理,可以实现对业务逻辑的隔离,提高代码的模块化能力,同时也是解霜。Spring主要提供了
Aspect切面、JoinPoint连接点、PointCut切入点、Advice增强等实现方式。

// 第一个* 代表任意返回值
// 第二个* 当表任意方法
//(..) 代表任意参数
// 匹配controller下面的所有共有方法。
@Pointcut("execution( public * com.uaf.xxx.controller..*.*(..))")

切面代码


import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * @author Fly
 * @filename WebLogAcpect
 * @description 日志切面
 * @date 2019/12/27 16:56
 */
@Aspect
@Component
public class WebLogAcpect {
    
    
	/**
	 * 切点
	 */
	@Pointcut("execution(public *  com.uaf.xxx.controller..*.*(..))")
	public void pointCut() {
    
    
	}

	@Before("pointCut()")
	public void before(JoinPoint joinPoint) throws Throwable {
    
    
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletResponse response = attributes.getResponse();
		// 获取切入的 Method
		MethodSignature joinPointObject = (MethodSignature) joinPoint.getSignature();

		Method method = joinPointObject.getMethod();
		if (method.isAnnotationPresent(PostMapping.class)) {
    
    
			/** 值*/
			Object[] args = joinPoint.getArgs();
			/** 参数名*/
			String[] argNames = joinPointObject.getParameterNames();
			/** 获取参数类型*/
			Class[] paramTypes = joinPointObject.getParameterTypes();
			Map<String, Object> map = new HashMap();
			for (int i = 0; i < argNames.length; i++) {
    
    
				if (!paramTypes[i].getName().equals("javax.servlet.http.HttpServletRequest") && !paramTypes[i].getName()
						.equals("javax.servlet.http.HttpServletResponse") && !paramTypes[i].getName()
						.equals("org.springframework.web.multipart.MultipartFile") && !paramTypes[i].getName()
						.equals("org.apache.catalina.servlet4preview.http.HttpServletRequest")) {
    
    
					if (args[i] instanceof Object) {
    
    
						try {
    
    
							map = JSON.parseObject(JSON.toJSONString(args[i]), Map.class);
						} catch (Exception e) {
    
    
							map.put(argNames[i], args[i]);
						}
						map.remove("key");
						map.remove("newKey");
					}
				}
			}
			/** 转换成json*/
			JSONObject json = (JSONObject) JSONObject.toJSON(map);
			screenParam("[前置输出VO]", json, joinPointObject.getDeclaringTypeName(), joinPointObject.getName(), "参数");
		}
	}

	@AfterReturning(value = "pointCut()", returning = "keys")//后置通知
	public void After(JoinPoint joinPoint, Object keys) throws Exception {
    
    
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletResponse response = attributes.getResponse();
		// 获取切入的 Method
		MethodSignature joinPointObject = (MethodSignature) joinPoint.getSignature();
		JSONObject json = (JSONObject) JSONObject.toJSON(keys);
		screenParam("[后置输出VO]", json, joinPointObject.getDeclaringTypeName(), joinPointObject.getName(), "返回值");
	}

	/**
	 * 筛选数据,不符合规则的不打印
	 */
	public void screenParam(String position, JSONObject jsonObject, String typeName, String methodName,
			String paramsName) throws Exception {
    
    
		MySlf4j.textInfo("{0}路径:{1},方法名:{2},{3}:{4}", position, typeName, methodName, paramsName,
				JSON.toJSONString(jsonObject));
	}
}

猜你喜欢

转载自blog.csdn.net/python_mopagunda/article/details/128797997