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));
}
}