Java注解实现动态拼接参数

现有需求
@Log(description = "{a}查询{b}的数据")
动态拼接参数保存到数据库中,就像redis缓存中key的动态拼接,@Cacheable(value="RptGroupAgent",key="'localAgentName'+#localAgentName") 。
接下来我们通过自定义注解来实现这个功能。
新增注解
import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {

    String  methodDesc() default "";

    String  description() default "";

}

 对应的AOP

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAdvice {

    @Autowired
    private static final Logger logger=LoggerFactory.getLogger(LogAdvice.class);

    @Pointcut("@annotation(注解路径)")
    public void serviceAspect() {
    }

    @After("serviceAspect()")
    public void after(JoinPoint joinPoint) throws IOException {
        logger.info("开始记录日志*************************");

        MethodSignature ms = (MethodSignature) joinPoint.getSignature();
        Method method = ms.getMethod();

        Log myAnnotation = method.getAnnotation(Log.class);

        Map paramsMap = new HashMap<>();
        String[] argNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames(); // 参数名
        Object[] argObjects = joinPoint.getArgs(); // 参数
        List argNameList = Arrays.asList(argNames);
        resolveArgs(joinPoint,argNameList,argObjects,paramsMap);

        saveToDbLog(myAnnotation,paramsMap);
    }

    @AfterReturning(pointcut = "serviceAspect()",returning="returnValue")
    public void afterreturningJoinPoint(JoinPoint joinPoint ,Object returnValue){
//        System.out.println("后置通知"+joinPoint+"返回值"+returnValue);
    }

    @Around("serviceAspect()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable{
        Object object = pjp.proceed();
        return object;
    }

    public static void saveToDbLog(Log myAnnotation, Map paramsMap){
        String description = myAnnotation.description();
        description = handleAnnotation(description,paramsMap);
        System.out.println(description);
     //TODO db操作 }
public static String handleAnnotation(String description, Map paramsMap){ AtomicReference result = new AtomicReference<>(description); if(StringUtils.isBlank(description)){ return result.get(); } paramsMap.entrySet().parallelStream().forEach(p->{ if(result.get().contains(p.getKey())){ result.set(result.get().replaceAll(p.getKey(), p.getValue() + "")); } }); return result.get(); } public static void resolveArgs(JoinPoint joinPoint, List argNameList, Object[] argObjects, Map paramsMap){ for(int i = 0; i < argNameList.size(); i++){ Class classo = argObjects[i].getClass(); if(handleClassType(classo.getName())){ paramsMap.put(argNameList.get(i),joinPoint.getArgs()[i]); continue; } JSONObject object = (JSONObject) JSONObject.toJSON(joinPoint.getArgs()[i]); object.keySet().parallelStream().forEach(p->{ paramsMap.put(p,object.get(p)); }); } } public static T get(Class clz,Object o){ if(clz.isInstance(o)){ return clz.cast(o); } return null; } public static boolean handleClassType(String name){ AtomicBoolean result = new AtomicBoolean(false); String[] className = {"String","Integer","Long","int","float","double","char"}; Arrays.asList(className).forEach(n->{ if(name.contains(n)) { result.set(name.contains(n)); } }); return result.get(); } }

 

 

你可能感兴趣的:(Java注解实现动态拼接参数)