spring-AOP 及 AOP获取request各项参数操作
spring-AOP 及 AOP获取request各项参数
AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待。
一、AOP的基本概念
Aspect
(切面):通常是一个类,里面可以定义切入点和通知JointPoint
(连接点):程序执行过程中明确的点,一般是方法的调用Advice
(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,aroundPointcut
(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式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中无问题
以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。
相关文章
- 这篇文章主要介绍了Spring AOP 对象内部方法间的嵌套调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-29
- 这篇文章主要给大家介绍了关于Nest.js参数校验和自定义返回数据格式的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-28
- 这篇文章主要介绍了Vue 组件复用多次自定义参数操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-27
如何在Spring WebFlux的任何地方获取Request对象
这篇文章主要介绍了如何在Spring WebFlux的任何地方获取Request对象,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下...2021-01-26- 这篇文章主要介绍了解决Springboot get请求是参数过长的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-17
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
废话不多说了,直接给大家贴代码了。<?php class test{} $a1 = null; $a2 = ""; //$a3 = $a4 = 0; $a5 = '0'; $a6 = false; $a7 = array(); //var $a8; $a9 = new test(); for ($i=1; $i <=9 ; $i++) {...2015-11-24- 这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
- mysql安装成功后有几个默认的配置模板,列表如下: my-huge.cnf : 用于高端产品服务器,包括1到2GB RAM,主要运行mysql my-innodb-heavy-4G.ini : 用于只有innodb的安装,最多有4GB RAM,支持大的查询和低流量 my-large.cnf : 用于...2015-03-15
- 这篇文章主要介绍了C#泛型的类型参数约束的相关资料,文中讲解非常细致,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下...2020-07-31
- 这篇文章主要给大家介绍了关于C#中out参数、ref参数与值参数的用法及区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
C#中HttpWebRequest、WebClient、HttpClient的使用详解
这篇文章主要介绍了C#中HttpWebRequest、WebClient、HttpClient的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25处理@PathVariable注解允许参数为空、允许不传参数的问题
这篇文章主要介绍了处理@PathVariable注解允许参数为空、允许不传参数的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-23- 这篇文章主要介绍了Java线程池中的各个参数如何合理设置操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-19
- 这篇文章主要介绍了详解Java后端优雅验证参数合法性,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-18
- 这篇文章主要介绍了SpringBoot接口接收json参数解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-19
- 这篇文章主要介绍了vue+axios全局添加请求头和参数操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-24
- 这篇文章主要介绍了pytorch 实现冻结部分参数训练另一部分,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-27
- 这篇文章主要介绍了C#向线程中传递多个参数的解决方法(两种)的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了spring cloud gateway中如何读取请求参数的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-15
- 这篇文章主要介绍了Postman参数化实现过程及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-08-13