Springboot 自定义注解+AOP实现修改参数的值

需求

如果方法中有staffId或者orgId参数,如果传值那么不做任何处理,如果调用发没有传值,需要从ThreadLocal中获取登录信息取得这两个参数的值并赋值

自定义注解

package com.zkml.study.annotation;

import java.lang.annotation.*;

@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckNullParams {
    
}

实现AOP

package com.zkml.study.aop;

import com.izkml.mlyun.framework.common.context.ContextConstant;
import com.izkml.mlyun.framework.common.context.ContextHandler;
import com.zkml.study.annotation.CheckNullParams;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
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.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 校验staffId/orgId是否为空,如果为空,重新赋值,如果有值直接joinPoint.proceed()
 * ProceedingJoinPoint只能用在环绕通知上。
 */
@Slf4j
@Aspect
@Component
public class CheckNullParamsAspect {

    private static final List PARAMS = Arrays.asList("staffId", "orgId");
    private static final Map PARAM_2_KEY = new HashMap<>();

    static {
        PARAM_2_KEY.put("staffId", ContextConstant.CONTEXT_CURRENT_STAFF_ID);
        PARAM_2_KEY.put("orgId", ContextConstant.CONTEXT_CURRENT_ORG_ID);
    }

    @Pointcut("@annotation(com.zkml.study.annotation.CheckNullParams)")
    public void paramNotNull() {
    }

    @Around("paramNotNull()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {

        log.info("进入到环绕通知中");

        MethodSignature signature = ((MethodSignature) joinPoint.getSignature());
        //得到拦截的方法
        Method method = signature.getMethod();
        //获取方法上的注解
        Annotation parameterAnnotations = method.getAnnotation(CheckNullParams.class);
        if (parameterAnnotations == null) {
            return joinPoint.proceed();
        }

        // 2、打印请求参数
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 全路径类名
        String target = joinPoint.getSignature().getDeclaringTypeName();
        // 类名截取
        String classNm = target.substring(target.lastIndexOf(".") + 1, target.length());
        
        // 参数值
        Object[] args = joinPoint.getArgs();

		/*参数名称数组(与args参数值意义对应)*/
        // 参数名
        String[] argNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
        for (int i = 0; i < argNames.length; i++) {
            if (!isPrimite(((MethodSignature) joinPoint.getSignature()).getParameterTypes()[i])) {
                Object obj = args[i];
                if (obj == null) {
                    continue;
                }
                Field field;
                for (String filedName : PARAMS) {
                    try {
                        field = obj.getClass().getDeclaredField(filedName);
                    } catch (NoSuchFieldException e) {
                        continue;
                    }
                    field.setAccessible(true);
                    if (field != null) {
                        field.set(obj, ContextHandler.getString(PARAM_2_KEY.get(filedName)));
                    }
                }
            } else {
                if (args[i] == null && PARAMS.contains(argNames[i])) {
                    args[i] = ContextHandler.getString(PARAM_2_KEY.get(argNames[i]));
                }
            }
        }
        log.info("{}.{} 接收参数: {}", classNm, method, Arrays.toString(args));
        return joinPoint.proceed(args);
    }

    /**
     * @param params
     * @return
     * @Author: Fangh
     * @Date: 2021-03-09 09:10:40
     * @Description: 重新赋值参数
     **/
    private Map reSetParams(Map params) {
        if (params.containsKey("staffId")) {
            String staffId = MapUtils.getString(params, "staffId", (String) ContextHandler.getAll().get(ContextConstant.CONTEXT_CURRENT_STAFF_ID));
            params.put("staffId", staffId);
        }
        if (params.containsKey("orgId")) {
            String orgId = MapUtils.getString(params, "orgId", (String) ContextHandler.getAll().get(ContextConstant.CONTEXT_CURRENT_ORG_ID));
            params.put("orgId", orgId);
        }
        return params;
    }

    /**
     * @param request
     * @return
     * @Author: Fangh
     * @Date: 2021-03-09 08:58:50
     * @Description: 获取请求参数
     **/
    public static Map getAllRequestParam(HttpServletRequest request) {
        Map res = new HashMap<>();
        Enumeration temp = request.getParameterNames();
        if (null != temp) {
            while (temp.hasMoreElements()) {
                String en = (String) temp.nextElement();
                String value = request.getParameter(en);
                res.put(en, value);
                // 在报文上送时,如果字段的值为空,则不上送<下面的处理为在获取所有参数数据时,判断若值为空,则删除这个字段>
                if (StringUtils.isEmpty(res.get(en))) {
                    res.remove(en);
                }
            }
        }
        return res;
    }

    /**
     * @param clazz
     * @return
     * @Author: Fangh
     * @Date: 2021-03-09 08:59:05
     * @Description: 判断是否为基本类型:包括String
     **/
    private boolean isPrimite(Class clazz) {
        if (clazz.isPrimitive() || clazz == String.class) {
            return true;
        } else {
            return false;
        }
    }
}

你可能感兴趣的:(springboot,#,java-动态代理,#,java核心知识点,aop,springboot,拦截器)