使用spring通過aop獲取方法參數(shù)和參數(shù)值
spring通過aop獲取方法參數(shù)和參數(shù)值
自定義注解
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(); // 參數(shù)值 Object[] args = joinPoint.getArgs(); Class<?>[] classes = new Class[args.length]; for (int k = 0; k < args.length; k++) { if (!args[k].getClass().isPrimitive()) { // 獲取的是封裝類型而不是基礎(chǔ)類型 String result = args[k].getClass().getName(); Class s = map.get(result); classes[k] = s == null ? args[k].getClass() : s; } } ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer(); // 獲取指定的方法,第二個(gè)參數(shù)可以不傳,但是為了防止有重載的現(xiàn)象,還是需要傳入?yún)?shù)的類型 Method method = Class.forName(classType).getMethod(methodName, classes); // 參數(shù)名 String[] parameterNames = pnd.getParameterNames(method); // 通過map封裝參數(shù)和參數(shù)值 HashMap<String, Object> paramMap = new HashMap(); for (int i = 0; i < parameterNames.length; i++) { paramMap.put(parameterNames[i], args[i]); System.out.println("參數(shù)名:"+parameterNames[i]+"\n參數(shù)值"+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切面 注解、參數(shù)獲取
在工作中會(huì)經(jīng)常使用aop,這里將aop使用基本方法,獲取在切點(diǎn)中使用的獲取參數(shù)、注解做一個(gè)樣例。
1、定義需要切面的注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AnnDemo { String value(); boolean isAop() default true; }
2、在需要進(jìn)行切面的方法標(biāo)注注解
@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、定義切面
在切面中獲取切點(diǎn)注解,方法,參數(shù)的獲取
@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(); //獲取注解標(biāo)注的方法 Method method = target.getClass().getMethod(msg.getName(), msg.getParameterTypes()); //通過方法獲取注解 AnnDemo annotation = method.getAnnotation(AnnDemo.class); Object proceed; //獲取參數(shù) 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("進(jìn)入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; } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot深入分析webmvc和webflux的區(qū)別
這篇文章主要介紹了SpringBoot深入分析webmvc和webflux的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-02-02Java使用openOffice對(duì)于word的轉(zhuǎn)換及遇到的問題解決
開發(fā)過程中經(jīng)常會(huì)使用java將office系列文檔轉(zhuǎn)換為PDF, 一般都使用微軟提供的openoffice+jodconverter 實(shí)現(xiàn)轉(zhuǎn)換文檔,下面這篇文章主要給大家介紹了關(guān)于Java通過openOffice對(duì)于word的轉(zhuǎn)換及遇到問題的解決方法,需要的朋友可以參考下2018-09-09Java concurrency線程池之Callable和Future_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了Java concurrency線程池之Callable和Future,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06Struts2實(shí)現(xiàn)CRUD(增 刪 改 查)功能實(shí)例代碼
CRUD是Create(創(chuàng)建)、Read(讀取)、Update(更新)和Delete(刪除)的縮寫,它是普通應(yīng)用程序的縮影。接下來通過本文給大家介紹Struts2實(shí)現(xiàn)CRUD(增 刪 改 查)功能實(shí)例代碼,感興趣的朋友一起看看吧2016-06-06SpringBoot整合Shiro實(shí)現(xiàn)登錄認(rèn)證的方法
這篇文章主要介紹了SpringBoot整合Shiro實(shí)現(xiàn)登錄認(rèn)證的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02