使用spring通过aop获取方法参数和参数值
更新时间:2021年9月12日 12:00 点击:2118
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; } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。
相关文章
- 这篇文章主要介绍了Spring AOP 对象内部方法间的嵌套调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-29
Spring Cloud 中@FeignClient注解中的contextId属性详解
这篇文章主要介绍了Spring Cloud 中@FeignClient注解中的contextId属性详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-25Springboot如何实现Web系统License授权认证
这篇文章主要介绍了Springboot如何实现Web系统License授权认证,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-28如何在Spring WebFlux的任何地方获取Request对象
这篇文章主要介绍了如何在Spring WebFlux的任何地方获取Request对象,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下...2021-01-26- 这篇文章主要介绍了详解SpringCloudGateway内存泄漏问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-16
- @Autowired 注解的主要功能就是完成自动注入,使用也非常简单,但这篇文章主要给大家介绍了关于Spring为什么不推荐使用@Autowired注解的相关资料,需要的朋友可以参考下...2021-11-03
Springboot如何使用mybatis实现拦截SQL分页
这篇文章主要介绍了Springboot使用mybatis实现拦截SQL分页,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-19- 这篇文章主要介绍了SpringMVC文件上传原理及实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-07-15
Spring Data JPA 关键字Exists的用法说明
这篇文章主要介绍了Spring Data JPA 关键字Exists的用法说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-10- 这篇文章主要介绍了C# 如何解析获取Url参数值,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2020-09-01
tomcat启动完成执行 某个方法 定时任务(Spring)操作
这篇文章主要介绍了tomcat启动完成执行 某个方法 定时任务(Spring)操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-25使用Maven 搭建 Spring MVC 本地部署Tomcat的详细教程
这篇文章主要介绍了使用Maven 搭建 Spring MVC 本地部署Tomcat,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-08-16- 这篇文章主要介绍了Spring Cloud负载均衡及远程调用实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2021-09-18
- 这篇文章主要介绍了SpringMvc自动装箱及GET请求参数原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-19
- 这篇文章主要介绍了Springboot使用thymeleaf动态模板实现刷新,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-08-31
- 这篇文章主要介绍了SpringMvc获取请求头请求体消息过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-17
Idea打包springboot项目没有.original文件解决方案
这篇文章主要介绍了Idea打包springboot项目没有.original文件解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-07-26- 这篇文章主要介绍了spring boot 使用utf8mb4的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-20
Springmvc ResponseBody响应json数据实现过程
这篇文章主要介绍了Springmvc ResponseBody响应json数据实现过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-10-26- 这篇文章主要介绍了SpringData Repository接口用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-08-27