springAop切⾯中的@Before@Around等执⾏顺序与请求参数统
⼀解码springboot实现aop
1.背景
  在实际开发中,我可能会对请求接⼝做统⼀⽇志输出,或者统⼀参数解析,验签,统⼀响应加密等,通常会⽤到aop,实际案例如下
2.代码
package com.qianxingniwo.log;
import com.alibaba.fastjson.JSON;
import ption.ParamException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.t.request.RequestContextHolder;
import org.t.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import flect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @Copyright (C)
* @Author:
* @Date: 2019/4/8 10:11
* @Description: <p>
* aop的⼏个重要概念
* 切⾯(做什么事情,切⼊后要执⾏的业务)
* 切⼊点(在什么地点,具体到⽅法,⼀般使⽤通配符或注解)
* 切⼊时机(在什么时候,⽅法执⾏前,⽅法执⾏后,抛异常的时候)
* </p>
*/
@Aspect//定义切⾯
@Component //加⼊spring容器
@SuppressWarnings("all")//注解主要⽤在取消⼀些编译器产⽣的警告
public class SystemLogAspect {
/**
* 本地异常⽇志记录对象
*/
private static final Logger log = Logger(SystemLogAspect.class);
/**
* Controller层切点
*/
@Pointcut("execution(* com.qianxingniwo.*.controller.*Controller.*(..))")
public void controllerAspect() {
}
/**
* 可以修改请求参数,如实际⽣成中,将请求参数解密等
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("controllerAspect()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("@Around=1=⽅法执⾏前" + System.currentTimeMillis());
Object[] obj = Args();
System.out.println("@Around=2=请求参数" + JSONString(obj));
//  Object obj2 = joinPoint.proceed();
// System.out.println("@Around=3=⽅法后" + System.currentTimeMillis() + "--" + obj2);
//  System.out.println("@Around:被织⼊的⽬标对象为:" + Target());
//  System.out.println("@Around:原返回值:" + JSONString(obj2) + ",这是返回结果的后缀");
// JSONObject jsonObject = JSON.JSONString(obj[0]));
//通过反射实例化参数对象
//获取字节码
Class<?> aClass = obj[0].getClass();
//实例化对象
Object instance = wInstance();
//获取执⾏⽅法获取⽗类⽅法 setDataList
//Method method = DeclaredMethod("put", Object.class);
Method method = Superclass().getMethod("put", Object.class);
List<Integer> dataList = new ArrayList<>();
dataList.add(1);
dataList.add(2);
//执⾏⽅法
method.invoke(instance, dataList);
// jsonObject.put("dataList", dataList);
obj[0] = instance;
//obj[0] = MAPPER.writeValueAsString("");
System.out.println("=====修改参数==========");
return joinPoint.proceed(obj);
}
/**
* 切⼊时机
*
* @param joinPoint
* @Description 前置通知⽤于拦截Controller层记录⽤户的操作
*/
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) throws ParamException {
System.out.println("@Before==" + System.currentTimeMillis());
HttpServletRequest request = ((ServletRequestAttributes) RequestAttributes()).getRequest();        Thread.currentThread().setName(UUID.randomUUID().toString().substring(0, 12));
String params = "";
if (Args() != null && Args().length > 0) {
String data = Args()[0]);
params += data;
}
//获取⽤户请求⽅法的参数并序列化为JSON格式字符串
//打印请求内容
String url = RequestURL().toString();
log.info("===============请求内容===============");
log.info("请求地址:" + url);
log.info("请求⽅式:" + Method());
log.info("请求类⽅法:" + Signature());
log.info("请求类⽅法参数:" + params);
log.info("===============请求内容===============");
}
@After("controllerAspect()")
public void After(JoinPoint point) {
System.out.println("@After==" + System.currentTimeMillis());
/* System.out.println("@After:模拟释放资源...");
System.out.println("@After:⽬标⽅法为:" +
"." + Signature().getName());
System.out.println("@After:参数为:" + Args()));
System.out.println("@After:被织⼊的⽬标对象为:" + Target());*/
}
/**
* 统⼀修改响应结果,如加密等
*
* @param joinPoint
* @param o
* @throws Exception
*/
@AfterReturning(returning = "o", pointcut = "controllerAspect()")
public void methodAfterReturing(JoinPoint joinPoint, Object o) throws Exception {
System.out.println("@AfterReturning==" + System.currentTimeMillis());
System.out.println("@AfterReturning:模拟⽇志记录功能...");
log.info("--------------返回内容----------------");
log.info("Response内容:" + JSONString(o));
log.info("--------------返回内容----------------");
/
* ResponseMessage responseMessage = (ResponseMessage) o;
byte[] a = JSONString(o).getBytes());
responseMessage.setMsg(new String(a ));
log.info("请求返回值【{}】", String());*/
}
@AfterThrowing("controllerAspect()")
public void AfterThrowing() {
System.out.println("@AfterThrowing==" + System.currentTimeMillis());
System.out.println("异常通知....");
}
}
  执⾏结果如下:
3.执⾏流程图解
4.aop统⼀处理空字符串转为null的处理 
package common.aop;
import com.alibaba.fastjson.JSON;
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.springframework.stereotype.Component;
import flect.Field;
import flect.Method;
/**
* @Copyright (C)
* @Author: LI DONG PING
* @Date: 2020-10-20 11:15
* @Description:
*/
@Aspect
@Component
@SuppressWarnings("all")
public class ParamAspect {
/**
*
*/
@Pointcut("execution(* ller.*Controller.*(..))")
public void controllerAspect2() {
}
@Pointcut("execution(* common.base.BaseController.*(..))")
public void controllerAspect() {
}
/**
* 将空字符串参数设置为null
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("controllerAspect() || controllerAspect2()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] obj = Args();
for (int i = 0; i < obj.length; i++) {
Object o = obj[i];
String jsonString = JSONString(o);
Class<?> aClass = o.getClass();
Field[] fields = DeclaredFields();
for (int j = 0; j < fields.length; j++) {
String fieldName = fields[j].getName();
if ("serialVersionUID".equals(fieldName)) {
continue;
}
Class type = fields[j].getType();
if (type != String.class) {
continue;
}
Object value = Method("get" + upperCase(fieldName)).invoke(o);
if (value != null && "".String())) {
Method method = o.getClass().getMethod("set" + upperCase(fieldName), type);
/
/将值设为null
method.invoke(o, new Object[]{null});
}
}
}
return joinPoint.proceed(obj);
}
public String upperCase(String str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
}
完美!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。