您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“怎么使用Spring AOP預(yù)處理Controller的參數(shù)”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“怎么使用Spring AOP預(yù)處理Controller的參數(shù)”這篇文章吧。
實(shí)際編程中,可能會(huì)有這樣一種情況,前臺(tái)傳過來的參數(shù),我們需要一定的處理才能使用
@Controller public class MatchOddsController { @Autowired private MatchOddsServcie matchOddsService; @RequestMapping(value = "/listOdds", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE}) @ResponseBody public List<OddsModel> listOdds(@RequestParam Date startDate, @RequestParam Date endDate) { return matchOddsService.listOdds(startDate, endDate); } }
前臺(tái)傳過來的startDate和endDate是兩個(gè)日期,實(shí)際使用中我們需要將之轉(zhuǎn)換為兩個(gè)日期對(duì)應(yīng)的當(dāng)天11點(diǎn),如果只有這么一個(gè)類的話,我們是可以直接在方法最前面處理就可以了
@Controller public class MatchProductController { @Autowired private MatchProductService matchProductService; @RequestMapping(value = "/listProduct", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE }) @ResponseBody public List<ProductModel> listProduct(@RequestParam Date startDate, @RequestParam Date endDate) { return matchProductService.listMatchProduct(startDate, endDate); } }
@Controller public class MatchController { @Autowired private MatchService matchService; @RequestMapping(value = "/listMatch", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE}) @ResponseBody public List<MatchModel> listMatch(@RequestParam Date startDate, @RequestParam Date endDate) { return matchService.listMatch(startDate, endDate); } }
當(dāng)然也可以寫兩個(gè)util方法,分別處理startDate和endDate,但是為了讓Controller看起來更干凈一些,我們還是用AOP來實(shí)現(xiàn)吧,順便為AOP更復(fù)雜的應(yīng)用做做鋪墊
本應(yīng)用中使用Configuration Class來進(jìn)行配置,
@SpringBootApplication @EnableAspectJAutoProxy(proxyTargetClass = true) //開啟AspectJ代理,并將proxyTargetClass置為true,表示啟用cglib對(duì)Class也進(jìn)行代理 public class Application extends SpringBootServletInitializer { ... }
@Aspect //1 @Configuration //2 public class SearchDateAspect { @Pointcut("execution(* com.ronnie.controller.*.list*(java.util.Date,java.util.Date)) && args(startDate,endDate)") //3 private void searchDatePointcut(Date startDate, Date endDate) { //4 } @Around(value = "searchDatePointcut(startDate,endDate)", argNames = "startDate,endDate") //5 public Object dealSearchDate(ProceedingJoinPoint joinpoint, Date startDate, Date endDate) throws Throwable { //6 Object[] args = joinpoint.getArgs(); //7 if (args[0] == null) { args[0] = Calendars.getTodayEleven(); args[1] = DateUtils.add(new Date(), 7, TimeUnit.DAYS);//默認(rèn)顯示今天及以后的所有賠率 } else { args[0] = DateUtils.addHours(startDate, 11); args[1] = DateUtils.addHours(endDate, 11); } return joinpoint.proceed(args); //8 } }
表示這是一個(gè)切面類
表示這個(gè)類是一個(gè)配置類,在ApplicationContext啟動(dòng)時(shí)會(huì)加載配置,將這個(gè)類掃描到
定義一個(gè)切點(diǎn),execution(* com.ronnie.controller.*.list*(java.util.Date,java.util.Date))表示任意返回值,在com.ronnie.controller包下任意類的以list開頭的方法,方法帶有兩個(gè)Date類型的參數(shù),args(startDate,endDate)表示需要Spring傳入這兩個(gè)參數(shù)
定義切點(diǎn)的名稱
配置環(huán)繞通知
ProceedingJoinPoint會(huì)自動(dòng)傳入,用于處理真實(shí)的調(diào)用
獲取參數(shù),下面代碼是修改參數(shù)
使用修改過的參數(shù)調(diào)用目標(biāo)類
更多可參考
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/
由于項(xiàng)目中打印日志的需要,研究了一下在aop中,獲取參數(shù)名稱的方法。
Signature signature = joinpoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; String[] strings = methodSignature.getParameterNames(); System.out.println(Arrays.toString(strings));
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable{ String classType = joinPoint.getTarget().getClass().getName(); Class<?> clazz = Class.forName(classType); String clazzName = clazz.getName(); String methodName = joinPoint.getSignature().getName(); //獲取方法名稱 Object[] args = joinPoint.getArgs();//參數(shù) //獲取參數(shù)名稱和值 Map<String,Object > nameAndArgs = getFieldsName(this.getClass(), clazzName, methodName,args); System.out.println(nameAndArgs.toString()); //為了省事,其他代碼就不寫了, return result = joinPoint.proceed(); }
private Map<String,Object> getFieldsName(Class cls, String clazzName, String methodName, Object[] args) throws NotFoundException { Map<String,Object > map=new HashMap<String,Object>(); ClassPool pool = ClassPool.getDefault(); //ClassClassPath classPath = new ClassClassPath(this.getClass()); ClassClassPath classPath = new ClassClassPath(cls); pool.insertClassPath(classPath); CtClass cc = pool.get(clazzName); CtMethod cm = cc.getDeclaredMethod(methodName); MethodInfo methodInfo = cm.getMethodInfo(); CodeAttribute codeAttribute = methodInfo.getCodeAttribute(); LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag); if (attr == null) { // exception } // String[] paramNames = new String[cm.getParameterTypes().length]; int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1; for (int i = 0; i < cm.getParameterTypes().length; i++){ map.put( attr.variableName(i + pos),args[i]);//paramNames即參數(shù)名 } //Map<> return map; }
以上是“怎么使用Spring AOP預(yù)處理Controller的參數(shù)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。