一、定义注解
package com.github.dgw.annotation;
import com.github.dgw.enums.InterfaceType;
import java.lang.annotation.*;
/**
* 封装远程调用api 注解
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InvokeInterfaceLog {
//请求url
String requestUrl() default "";
//入参字段
String[] params() default {};
//回参字段
String[] result() default {};
//方法名称
String methodName() default "";
//业务关联唯一id
String uniqueId() default "";
//接口类型
InterfaceType interfaceType() default InterfaceType.TEST_INTERFACE_TYPE;
}
二、定义解析类
package com.github.dgw.config;
import com.github.dgw.annotation.InvokeInterfaceLog;
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.aop.aspectj.MethodInvocationProceedingJoinPoint;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
@Aspect
@Component
public class InvokeInterfaceLogAspect {
private final static Logger logger= LoggerFactory.getLogger(InvokeInterfaceLogAspect.class);
//只切带RedisLock注解的方法
@Pointcut("@annotation(com.github.dgw.annotation.InvokeInterfaceLog)")
public void executeService(){
}
/**
* 环绕通知
* @return
* @throws Throwable
*/
@Around("executeService()")
public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
//1,获取方法参数,作为redis存储时的key
// Map<String, Object> methodParam = getMethodParam(proceedingJoinPoint);
return proceedingJoinPoint.proceed();
}
/**
* 后置通知,方法调用后被调用(取不到返回值)
*/
@After("executeService()")
public void doAfterAdvice(JoinPoint joinPoint){
// Map<String, Object> methodParam = getMethodParam(joinPoint);
// System.out.println(methodParam);
}
/**
* 后置返回通知
*/
@AfterReturning(pointcut="executeService()",returning="result")
public void doAfterReturningAdvice(JoinPoint joinPoint,Object result){
Map<String, Object> methodParam = getMethodParam(joinPoint);
String[] params = (String[]) methodParam.get("params");
Map<String,Object> p=new HashMap<>();
Object[] args = joinPoint.getArgs();
System.out.println(methodParam.get("requestUrl"));
System.out.println(methodParam.get("params"));
System.out.println(methodParam.get("result"));
System.out.println(methodParam.get("methodName"));
System.out.println(methodParam.get("uniqueId"));
System.out.println(methodParam.get("interfaceType"));
}
//获取注解方法参数
private Map<String, Object> getMethodParam(JoinPoint joinPoint){
Class target = joinPoint.getTarget().getClass();
Method[] methods = target.getMethods();
String methodName = joinPoint.getSignature().getName();
for(Method method:methods){
if(method.getName().equals(methodName)){
Map<String, Object> result = new HashMap<String, Object>();
InvokeInterfaceLog annotation = method.getAnnotation(InvokeInterfaceLog.class);
String uniqueId = parseKey(annotation.uniqueId(), method, joinPoint.getArgs());
result.put("requestUrl", annotation.requestUrl());
result.put("params", annotation.params());
result.put("result", annotation.result());
result.put("methodName", annotation.methodName().equals("")?methodName:annotation.methodName());
result.put("uniqueId", uniqueId);
result.put("interfaceType", annotation.interfaceType());
return result;
}
}
return null;
}
/**
* 获取缓存的key
* key 定义在注解上,支持SPEL表达式
* @param
* @return
*/
private String parseKey(String key,Method method,Object [] args){
//获取被拦截方法参数名列表(使用Spring支持类库)
LocalVariableTableParameterNameDiscoverer u =new LocalVariableTableParameterNameDiscoverer();
String [] paraNameArr=u.getParameterNames(method);
//使用SPEL进行key的解析
ExpressionParser parser = new SpelExpressionParser();
//SPEL上下文
StandardEvaluationContext context = new StandardEvaluationContext();
//把方法参数放入SPEL上下文中
for(int i=0;i<paraNameArr.length;i++){
context.setVariable(paraNameArr[i], args[i]);
}
return parser.parseExpression(key).getValue(context,String.class);
}
}