百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Spring-AOP 及 AOP获取request各项参数操作

wxin55 2024-10-27 15:56 13 浏览 0 评论

Spring-AOP 及 AOP获取request各项参数

AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待。

一、AOP的基本概念

  • Aspect(切面):通常是一个类,里面可以定义切入点和通知
  • JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用
  • Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around
  • Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式
  • AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以是JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类

二、Spring AOP

Spring中的AOP代理还是离不开Spring的IOC容器,代理的生成,管理及其依赖关系都是由IOC容器负责,Spring默认使用JDK动态代理,在需要代理类而不是代理接口的时候,Spring会自动切换为使用CGLIB代理,不过现在的项目都是面向接口编程,所以JDK动态代理相对来说用的还是多一些。

三、基于注解的AOP配置方式

1.启用@AsjectJ支持

在spring配置中配置下面一句:

<aop:aspectj-autoproxy />

或者使用注解:

@EnableAspectJAutoProxy

2.通知类型介绍

(1) Before:在目标方法被调用之前做增强处理,@Before只需要指定切入点表达式即可

(2) AfterReturning:在目标方法正常完成后做增强,@AfterReturning除了指定切入点表达式后,还可以指定一个返回值形参名returning,代表目标方法的返回值

(3) AfterThrowing:主要用来处理程序中未处理的异常,@AfterThrowing除了指定切入点表达式后,还可以指定一个throwing的返回值形参名,可以通过该形参名

来访问目标方法中所抛出的异常对象

(4) After:在目标方法完成之后做增强,无论目标方法时候成功完成。@After可以指定一个切入点表达式

(5) Around:环绕通知,在目标方法完成前后做增强处理,环绕通知是最重要的通知类型,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint

3.通知执行的优先级

进入目标方法时,先织入Around,再织入Before,退出目标方法时,先织入Around,再织入AfterReturning,最后才织入After。

注意:Spring AOP的环绕通知会影响到AfterThrowing通知的运行,不要同时使用!同时使用也没啥意义。

4.切入点的定义和表达式

切入点表达式的定义算是整个AOP中的核心,有一套自己的规范

Spring AOP支持的切入点指示符:

execution:用来匹配执行方法的连接点

A:@Pointcut(“execution(* com.aijava.springcode.service….(…))”)

第一个表示匹配任意的方法返回值,…(两个点)表示零个或多个,上面的第一个…表示service包及其子包,第二个表示所有类,第三个*表示所有方法,第二个…表示

方法的任意参数个数

B:@Pointcut(“within(com.aijava.springcode.service.*)”)

within限定匹配方法的连接点,上面的就是表示匹配service包下的任意连接点

C:@Pointcut(“this(com.aijava.springcode.service.UserService)”)

this用来限定AOP代理必须是指定类型的实例,如上,指定了一个特定的实例,就是UserService

D:@Pointcut(“bean(userService)”)

bean也是非常常用的,bean可以指定IOC容器中的bean的名称

下面是一个使用AOP获取统计计算方法执行时间以及获取request请求参数等信息的log方法:

/**
 * description:
 * 统计请求执行时间
 *
 * @author wkGui
 */
@Component
@Aspect
public class ResExeTimeCounter {
    private static Logger logger = LoggerFactory.getLogger(ResExeTimeCounter.class);
    @Pointcut("execution(* com.wk.controller..*.*(..))")
    public void pointCut() {
    }
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        assert sra != null;
        HttpServletRequest request = sra.getRequest();
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String queryString = request.getQueryString();
        long startTime = System.currentTimeMillis();
        logger.info("{url:{}, method:{}, queryString:{}}", url, method, queryString);
        Object rs;
        boolean successAble = false;
        JsonObject paramsJson = new JsonObject();
        try {
            Object[] params = pjp.getArgs();
            for (int i = 0; i < params.length; i++) {
                if (params[i] instanceof BindingResult
                        || params[i] instanceof HttpRequest
                        || params[i] instanceof HttpResponse){
                    continue;
                }
                paramsJson.addProperty("param-" + i, JsonUtil.toJsonWtihNullField(params[i]));
            }
            rs = pjp.proceed();
            successAble = true;
        } finally {
            logger.info("{url:{}, method:{}, success-able:{}, exe-time:{}, params:{}}", url, method, successAble, System.currentTimeMillis() - startTime, paramsJson);
        }
        return rs;
    }
}

SpringAOP获取request中所有参数,记录用户操作日志

今天搞了一个AOP的管理日志,蛋疼得很....

老规矩贴代码吧

首先除了aop的包以外需要这三个包。

自行度娘。

如果想切入controllers,请将这个代码写入你的mvc配置中,纠结了一上午切不进去就是这个原因.

method为你切入类的方法名

可以照这个打个模版出来,PS:无视注释哈,逼死强迫症

因为我的控制类里面只会有两个参数request和response ,所以我这里request就直接等于了下标为0,

下面的

  Enumeration parameter = request.getParameterNames();
  while(parameter.hasMoreElements()) {
  String a=(String) parameter.nextElement();
  System.out.println(request.getParameter(a));
  }

可以获取从页面上传过来的所有参数以及参数名,参数:request.getParameter(a),参数名:a

上面的代码放在aop中实测可以,但如果放在拦截器中,实测会返回一个date,不知道什么鬼,get请求的话偶尔会正常。post一定不正常,aop中无问题

相关推荐

ES6中 Promise的使用场景?(es6promise用法例子)

一、介绍Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码doSomething(f...

JavaScript 对 Promise 并发的处理方法

Promise对象代表一个未来的值,它有三种状态:pending待定,这是Promise的初始状态,它可能成功,也可能失败,前途未卜fulfilled已完成,这是一种成功的状态,此时可以获取...

Promise的九大方法(promise的实例方法)

1、promise.resolv静态方法Promise.resolve(value)可以认为是newPromise方法的语法糖,比如Promise.resolve(42)可以认为是以下代码的语...

360前端一面~面试题解析(360前端开发面试题)

1.组件库按需加载怎么做的,具体打包配了什么-按需加载实现:借助打包工具(如Webpack的require.context或ES模块动态导入),在使用组件时才引入对应的代码。例如在V...

前端面试-Promise 的 finally 怎么实现的?如何在工作中使用?

Promise的finally方法是一个非常有用的工具,它无论Promise是成功(fulfilled)还是失败(rejected)都会执行,且不改变Promise的最终结果。它的实现原...

最简单手写Promise,30行代码理解Promise核心原理和发布订阅模式

看了全网手写Promise的,大部分对于新手还是比较难理解的,其中几个比较难的点:状态还未改变时通过发布订阅模式去收集事件实例化的时候通过调用构造函数里传出来的方法去修改类里面的状态,这个叫Re...

前端分享-Promise可以中途取消啦(promise可以取消吗)

传统Promise就像一台需要手动组装的设备,每次使用都要重新接线。而Promise.withResolvers的出现,相当于给开发者发了一个智能遥控器,可以随时随地控制异步操作。它解决了三大...

手写 Promise(手写输入法 中文)

前言都2020年了,Promise大家肯定都在用了,但是估计很多人对其原理还是一知半解,今天就让我们一起实现一个符合PromiseA+规范的Promise。附PromiseA+规范地址...

什么是 Promise.allSettled()!新手老手都要会?

Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的pr...

前端面试-关于Promise解析与高频面试题示范

Promise是啥,直接上图:Promise就是处理异步函数的API,它可以包裹一个异步函数,在异步函数完成时抛出完成状态,让代码结束远古时无限回掉的窘境。配合async/await语法糖,可...

宇宙厂:为什么前端离不开 Promise.withResolvers() ?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.为什么需要Promise.with...

Promise 新增了一个超实用的 API!

在JavaScript的世界里,Promise一直是处理异步操作的神器。而现在,随着ES2025的发布,Promise又迎来了一个超实用的新成员——Promise.try()!这个新方法简...

一次搞懂 Promise 异步处理(promise 异步顺序执行)

PromisePromise就像这个词的表面意识一样,表示一种承诺、许诺,会在后面给出一个结果,成功或者失败。现在已经成为了主流的异步编程的操作方式,写进了标准里面。状态Promise有且仅有...

Promise 核心机制详解(promise机制的实现原理)

一、Promise的核心状态机Promise本质上是一个状态机,其行为由内部状态严格管控。每个Promise实例在创建时处于Pending(等待)状态,此时异步操作尚未完成。当异步操作成功...

javascript——Promise(js实现promise)

1.PromiseES6开始支持,Promise对象用于一个异步操作的最终完成(包括成功和失败)及结果值的表示。简单说就是处理异步请求的。之所以叫Promise,就是我承诺,如果成功则怎么处理,失败怎...

取消回复欢迎 发表评论: