文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎么使用Spring AOP预处理Controller的参数

2023-06-20 20:32

关注

这篇文章主要为大家展示了“怎么使用Spring AOP预处理Controller的参数”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“怎么使用Spring AOP预处理Controller的参数”这篇文章吧。

Spring AOP预处理Controller的参数

实际编程中,可能会有这样一种情况,前台传过来的参数,我们需要一定的处理才能使用

比如有这样一个Controller

@Controllerpublic 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);    }}

前台传过来的startDate和endDate是两个日期,实际使用中我们需要将之转换为两个日期对应的当天11点,如果只有这么一个类的话,我们是可以直接在方法最前面处理就可以了

但是,还有下面两个类具有同样的业务逻辑

@Controllerpublic 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);    }}
@Controllerpublic 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);    }}

当然也可以写两个util方法,分别处理startDate和endDate,但是为了让Controller看起来更干净一些,我们还是用AOP来实现吧,顺便为AOP更复杂的应用做做铺垫

本应用中使用Configuration Class来进行配置,

主配置类如下:

@SpringBootApplication@EnableAspectJAutoProxy(proxyTargetClass = true) //开启AspectJ代理,并将proxyTargetClass置为true,表示启用cglib对Class也进行代理public class Application extends SpringBootServletInitializer {    ...}

下面新建一个Aspect类,代码如下

@Aspect //1@Configuration //2public 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);//默认显示今天及以后的所有赔率        } else {            args[0] = DateUtils.addHours(startDate, 11);            args[1] = DateUtils.addHours(endDate, 11);        }        return joinpoint.proceed(args); //8    }}

分别解释一下上面各个地方的意思,标号与语句之后的注释一致

  1. 表示这是一个切面类

  2. 表示这个类是一个配置类,在ApplicationContext启动时会加载配置,将这个类扫描到

  3. 定义一个切点,execution(* com.ronnie.controller.*.list*(java.util.Date,java.util.Date))表示任意返回值,在com.ronnie.controller包下任意类的以list开头的方法,方法带有两个Date类型的参数,args(startDate,endDate)表示需要Spring传入这两个参数

  4. 定义切点的名称

  5. 配置环绕通知

  6. ProceedingJoinPoint会自动传入,用于处理真实的调用

  7. 获取参数,下面代码是修改参数

  8. 使用修改过的参数调用目标类

更多可参考

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html

http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/

AOP获取参数名称

由于项目中打印日志的需要,研究了一下在aop中,获取参数名称的方法。

1、jdk1,8中比较简单,直接通过joinPoint中的getSignature()方法即可获取

Signature signature = joinpoint.getSignature();  MethodSignature methodSignature = (MethodSignature) signature;  String[] strings = methodSignature.getParameterNames();  System.out.println(Arrays.toString(strings));

怎么使用Spring AOP预处理Controller的参数

2.通用方法。比较麻烦

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();//参数            //获取参数名称和值          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即参数名            }                      //Map<>          return map;        }

以上是“怎么使用Spring AOP预处理Controller的参数”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯