一、实现方式
1.直接通过SpringCloud-GateWay 的GlobalFilter实现
2.AOP+反射+自定义注解自己封装
二、具体实现
1.自定义注解
@Target({ElementType.METHOD})//作用在方法上
@Retention(RetentionPolicy.RUNTIME)//运行时生效
public @interface MethodExporter{//自定义注解只是为了提供切入点
}
2.通用controller
@RestController
@Slf4j
public class MethodExporterController{//http://localhost:24618/method/list?page=1&rows=7@GetMapping(value = "/method/list")@MethodExporterpublic Map list(@RequestParam(value = "page",defaultValue = "1") int page,@RequestParam(value = "rows",defaultValue = "5")int rows){Map<String,String> result = new LinkedHashMap<>();result.put("code","200");result.put("message","success");//暂停毫秒try { TimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); }return result;}@MethodExporter@GetMapping(value = "/method/get")public Map get(){Map<String,String> result = new LinkedHashMap<>();result.put("code","404");result.put("message","not-found");//暂停毫秒try { TimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); }return result;}@GetMapping(value = "/method/update")public String update(){System.out.println("update method without @MethodExporter");return "ok update";}}
3.AOP切面类
@Aspect
@Component
@Slf4j
public class MethodExporterAspect
{//容器捞鱼,谁带着使用了MethodExporter注解将会触发Around业务逻辑@Around("@annotation(com.atguigu.interview2.annotations.MethodExporter)")public Object methodExporter(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{Object retValue = null;long startTime = System.currentTimeMillis();System.out.println("-----@Around环绕通知AAA-methodExporter");retValue = proceedingJoinPoint.proceed(); //放行long endTime = System.currentTimeMillis();long costTime = endTime - startTime;//1 获得重载后的方法名MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();Method method = signature.getMethod();//2 确定方法名后获得该方法上面配置的注解标签MyRedisCacheMethodExporter methodExporterAnnotation = method.getAnnotation(MethodExporter.class);if (methodExporterAnnotation != null){//3 获得方法里面的形参信息StringBuffer jsonInputParam = new StringBuffer();Object[] args = proceedingJoinPoint.getArgs();DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();String[] parameterNames = discoverer.getParameterNames(method);for (int i = 0; i < parameterNames.length; i++){jsonInputParam.append(parameterNames[i] + "\t" + args[i].toString()+";");}//4 将返回结果retValue序列化String jsonResult = null;if(retValue != null){jsonResult = new ObjectMapper().writeValueAsString(retValue);}else{jsonResult = "null";}log.info("\n方法分析上报中 " +"\n类名方法名:"+proceedingJoinPoint.getTarget().getClass().getName()+"."+proceedingJoinPoint.getSignature().getName()+"()"+"\n执行耗时:"+costTime+"毫秒"+"\n输入参数:"+jsonInputParam+""+"\n返回结果:"+jsonResult+"" +"\nover");System.out.println("-----@Around环绕通知BBB-methodExporter");}return retValue;}
}