使用spring通过aop获取方法参数和参数值

 

spring通过aop获取方法参数和参数值

自定义注解

package com.xiaolc.aspect;  
import java.lang.annotation.*; 
/**
* @author lc
* @date 2019/9/10
*/
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LiCheng {
}

切面

package com.xiaolc.aspect; 
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
* 获取方法上的注解值
*/
@Component
@Aspect
public class AuditAnnotationAspect {

  @Around("@annotation(liCheng))")
  private static Map getFieldsName(ProceedingJoinPoint joinPoint,LiCheng liCheng) throws ClassNotFoundException, NoSuchMethodException {
      String classType = joinPoint.getTarget().getClass().getName();
      String methodName = joinPoint.getSignature().getName();
      // 参数值
      Object[] args = joinPoint.getArgs();
      Class<?>[] classes = new Class[args.length];
      for (int k = 0; k < args.length; k++) {
          if (!args[k].getClass().isPrimitive()) {
              // 获取的是封装类型而不是基础类型
              String result = args[k].getClass().getName();
              Class s = map.get(result);
              classes[k] = s == null ? args[k].getClass() : s;
          }
      }
      ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();
      // 获取指定的方法,第二个参数可以不传,但是为了防止有重载的现象,还是需要传入参数的类型
      Method method = Class.forName(classType).getMethod(methodName, classes);
      // 参数名
      String[] parameterNames = pnd.getParameterNames(method);
      // 通过map封装参数和参数值
      HashMap<String, Object> paramMap = new HashMap();
      for (int i = 0; i < parameterNames.length; i++) {
          paramMap.put(parameterNames[i], args[i]);
          System.out.println("参数名:"+parameterNames[i]+"\n参数值"+args[i]);
      }
      return paramMap;
  }
  private static HashMap<String, Class> map = new HashMap<String, Class>() {
      {
          put("java.lang.Integer", int.class);
          put("java.lang.Double", double.class);
          put("java.lang.Float", float.class);
          put("java.lang.Long", Long.class);
          put("java.lang.Short", short.class);
          put("java.lang.Boolean", boolean.class);
          put("java.lang.Char", char.class);
      }
  };
}

 

aop切面 注解、参数获取

在工作中会经常使用aop,这里将aop使用基本方法,获取在切点中使用的获取参数、注解做一个样例。

1、定义需要切面的注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AnnDemo {
  String value();
  boolean isAop() default true;
}

2、在需要进行切面的方法标注注解

@RestController
@RequestMapping("/order")
public class OrderController {
  @Autowired
  private OrderService orderService;
  @RequestMapping("/all")
  @AnnDemo(value = "all",isAop = false)
  public List<TbOrder> findAll() {
      List<TbOrder> list = orderService.getOrderList();
      return list;
  }
  @RequestMapping("/page")
  @AnnDemo(value = "page")
  public List<TbOrder> findPage(@RequestParam("username") String username) {
      List<TbOrder> listPage = orderService.getOrdersListPage();
      return listPage;
  }
}

3、定义切面

在切面中获取切点注解,方法,参数的获取

@Aspect
@Component
public class AspectDemo {
  @Pointcut(value = "execution(* com.yin.freemakeradd.controller..*(..))")
  public void excetionMethod() {}
  @Pointcut(value = "execution(* com.yin.freemakeradd.controller..*(..)) && @annotation(AnnDemo)")
  public void excetionNote() { }
  @Before("excetionMethod()")
  public void testBefore(JoinPoint joinPoint) {
      System.out.println("----------------------------前置通知---");
      Object[] args = joinPoint.getArgs();
      for (Object arg : args) {
          System.out.println(arg);
      }
  }
  @Around(value = "execution(* com.yin.freemakeradd.controller..*(..)) && @annotation(AnnDemo)")
  public Object  testBeforeNote(ProceedingJoinPoint joinPoint) throws Throwable {
      //用的最多通知的签名
      Signature signature = joinPoint.getSignature();
      MethodSignature msg=(MethodSignature) signature;
      Object target = joinPoint.getTarget();
      //获取注解标注的方法
      Method method = target.getClass().getMethod(msg.getName(), msg.getParameterTypes());
      //通过方法获取注解
      AnnDemo annotation = method.getAnnotation(AnnDemo.class);
      Object proceed;
      //获取参数
      Object[] args = joinPoint.getArgs();
      System.out.println(annotation.value());
      System.out.println(annotation.isAop());
      for (Object arg : args) {
          System.out.println(arg);
      }
      if (Objects.isNull(annotation) || !annotation.isAop()) {
          System.out.println("无需处理");
          proceed = joinPoint.proceed();
      }else {
          System.out.println("进入aop判断");
          proceed = joinPoint.proceed();
          if(proceed instanceof List){
              List proceedLst = (List) proceed;
              if(!CollectionUtils.isEmpty(proceedLst)){
                  TbOrder tbOrder = new TbOrder();
                  tbOrder.setPaymentType("fffffffffffffffffff");
                  ArrayList<TbOrder> tbOrderLst = new ArrayList<>();
                  tbOrderLst.add(tbOrder);
                  return tbOrderLst;
              }
          }
          System.out.println(proceed);
      }
      return proceed;
  }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程宝库

 kafka消息堆积及分区不均匀的解决我在环境中发现代码里面的kafka有所延迟,查看kafka消息发现堆积严重,经过检查发现是kafka消息分区不均匀造成的,消费速度过慢。这里由自己在虚 ...