使用spring通过aop获取方法参数和参数值
目录
- spring通过aop获取方法参数和参数值
- 自定义注解
- 切面
- aop切面 注解、参数获取
- 1、定义需要切面的注解
- 2、在需要进行切面的方法标注注解
- 3、定义切面
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@Aspectpublic 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 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 map = new HashMap() {{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)@Documentedpublic @interface AnnDemo {String value(); boolean isAop() default true; }
2、在需要进行切面的方法标注注解
@RestController@RequestMapping("/order")public class OrderController {@Autowiredprivate OrderService orderService; @RequestMapping("/all")@AnnDemo(value = "https://www.it610.com/article/all",isAop = false)public ListfindAll() {List list = orderService.getOrderList(); return list; }@RequestMapping("/page")@AnnDemo(value = "https://www.it610.com/article/page")public List findPage(@RequestParam("username") String username) {List listPage = orderService.getOrdersListPage(); return listPage; }}
3、定义切面
在切面中获取切点注解,方法,参数的获取
@Aspect@Componentpublic class AspectDemo {@Pointcut(value = "https://www.it610.com/article/execution(* com.yin.freemakeradd.controller..*(..))")public void excetionMethod() {}@Pointcut(value = "https://www.it610.com/article/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 = "https://www.it610.com/article/execution(* com.yin.freemakeradd.controller..*(..)) && @annotation(AnnDemo)")public ObjecttestBeforeNote(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"); ArrayListtbOrderLst = new ArrayList<>(); tbOrderLst.add(tbOrder); return tbOrderLst; }}System.out.println(proceed); }return proceed; }}
【使用spring通过aop获取方法参数和参数值】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- Activiti(一)SpringBoot2集成Activiti6
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- gitlab|gitlab 通过备份还原 admin/runner 500 Internal Server Error
- iOS中的Block