软件编程
位置:首页>> 软件编程>> java编程>> 使用spring通过aop获取方法参数和参数值

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

作者:Insist_on_progress  发布时间:2022-06-04 16:28:33 

标签: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;
   }
}

来源:https://blog.csdn.net/qq_41988504/article/details/100726527

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com