现有需求
@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<String,Object> paramsMap = new HashMap<>(); String[] argNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames(); // 参数名 Object[] argObjects = joinPoint.getArgs(); // 参数 List<String> 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<String,Object> paramsMap){ String description = myAnnotation.description(); description = handleAnnotation(description,paramsMap); System.out.println(description);
//TODO db操作 } public static String handleAnnotation(String description, Map<String,Object> paramsMap){ AtomicReference<String> 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<String> argNameList, Object[] argObjects, Map<String,Object> 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> T get(Class<T> 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(); } }