java相关:springboot配置aop切面日志打印过程解析

发布于 2020-3-31|

复制链接

摘记: 这篇文章主要介绍了springboot配置aop切面日志打印过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下一、SpringBoot Aop说明

1. Aop

AOP(Aspect-Oriented Pr ..

这篇文章主要介绍了springboot配置aop切面日志打印过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下一、SpringBoot Aop说明1. Aop

AOP(Aspect-Oriented Programming,面向切面编程),它利用一种”横切”的技术,将那些多个类的共同行为封装到一个可重用的模块。便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。2. AOP相关概念:

Aspect(切面):声明类似于Java中的类声明,在Aspect中会包含一些Pointcut及相应的Advice。Joint point(连接点):表示在程序中明确定义的点。包括方法的调用、对类成员的访问等。Pointcut(切入点):表示一个组Joint point,如方法名、参数类型、返回类型等等。Advice(通知):Advice定义了在Pointcut里面定义的程序点具体要做的操作,它通过(before、around、after(return、throw)、finally来区别实在每个Joint point之前、之后还是执行 前后要调用的代码。Before:在执行方法前调用Advice,比如请求接口之前的登录验证。Around:在执行方法前后调用Advice,这是最常用的方法。After:在执行方法后调用Advice,after、return是方法正常返回后调用,after\throw是方法抛出异常后调用。Finally:方法调用后执行Advice,无论是否抛出异常还是正常返回。AOP proxy:AOP proxy也是Java对象,是由AOP框架创建,用来完成上述动作,AOP对象通常可以通过JDK dynamic proxy完成,或者使用CGLIb完成。Weaving:实现上述切面编程的代码织入,可以在编译时刻,也可以在运行时刻,Spring和其它大多数Java框架都是在运行时刻生成代理。二、代码示例

1. POM引入

```xml

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-aop

eu.bitwalker

UserAgentUtils

1.21

org.projectlombok

lombok

1.18.10

```

2、切面:WebLogAspect代码

```java

/**

* 添加aop日志打印

*

* @author 马振全 2020/1/13 14:42

*/

@Aspect

@Component

@Slf4j

public class WebLogAspect {

/**

* 进入方法时间戳

*/

private Long startTime;

/**

* 方法结束时间戳(计时)

*/

private Long endTime;

public WebLogAspect() {

}

/**

* 定义请求日志切入点,其切入点表达式有多种匹配方式,这里是指定路径

*/

@Pointcut("execution(public * com.soyoung.ad.engine.controller.*.*(..))")

public void webLogPointcut() {

}

/**

* 前置通知:

* 1. 在执行目标方法之前执行,比如请求接口之前的登录验证;

* 2. 在前置通知中设置请求日志信息,如开始时间,请求参数,注解内容等

*

* @param joinPoint

* @throws Throwable

*/

@Before("webLogPointcut()")

public void doBefore(JoinPoint joinPoint) {

// 接收到请求,记录请求内容

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

HttpServletRequest request = attributes.getRequest();

//获取请求头中的User-Agent

UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));

//打印请求的内容

startTime = System.currentTimeMillis();

log.info("请求开始时间:{}", LocalDateTime.now());

log.info("请求Url : {}", request.getRequestURL().toString());

log.info("请求方式 : {}", request.getMethod());

log.info("请求ip : {}", request.getRemoteAddr());

log.info("请求方法 : ", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());

log.info("请求参数 : {}", Arrays.toString(joinPoint.getArgs()));

// 系统信息

log.info("浏览器:{}", userAgent.getBrowser().toString());

log.info("浏览器版本:{}", userAgent.getBrowserVersion());

log.info("操作系统: {}", userAgent.getOperatingSystem().toString());

}

/**

* 返回通知:

* 1. 在目标方法正常结束之后执行

* 1. 在返回通知中补充请求日志信息,如返回时间,方法耗时,返回值,并且保存日志信息

*

* @param ret

* @throws Throwable

*/

@AfterReturning(returning = "ret", pointcut = "webLogPointcut()")

public void doAfterReturning(Object ret) throws Throwable {

endTime = System.currentTimeMillis();

log.info("请求结束时间:{}", LocalDateTime.now());

log.info("请求耗时:{}", (endTime - startTime));

// 处理完请求,返回内容

log.info("请求返回 : {}", ret);

}

/**

* 异常通知:

* 1. 在目标方法非正常结束,发生异常或者抛出异常时执行

* 1. 在异常通知中设置异常信息,并将其保存

*

* @param throwable

*/

@AfterThrowing(value = "webLogPointcut()", throwing = "throwable")

public void doAfterThrowing(Throwable throwable) {

// 保存异常日志记录

log.error("发生异常时间:{}", LocalDateTime.now());

log.error("抛出异常:{}", throwable.getMessage());

}

}

```

3、@Before和@AfterReturning部分也可使用以下代码替代

```java

/**

* 在执行方法前后调用Advice,这是最常用的方法,相当于@Before和@AfterReturning全部做的事儿

* @param pjp

* @return

* @throws Throwable

*/

@Around("webLogPointcut()")

public Object doAround(ProceedingJoinPoint pjp) throws Throwable {

// 接收到请求,记录请求内容

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

HttpServletRequest request = attributes.getRequest();

//获取请求头中的User-Agent

UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));

//打印请求的内容

startTime = System.currentTimeMillis();

log.info("请求Url : {}" , request.getRequestURL().toString());

log.info("请求方式 : {}" , request.getMethod());

log.info("请求ip : {}" , request.getRemoteAddr());

log.info("请求方法 : " , pjp.getSignature().getDeclaringTypeName() , "." , pjp.getSignature().getName());

log.info("请求参数 : {}" , Arrays.toString(pjp.getArgs()));

// 系统信息

log.info("浏览器:{}", userAgent.getBrowser().toString());

log.info("浏览器版本:{}",userAgent.getBrowserVersion());

log.info("操作系统: {}", userAgent.getOperatingSystem().toString());

// pjp.proceed():当我们执行完切面代码之后,还有继续处理业务相关的代码。proceed()方法会继续执行业务代码,并且其返回值,就是业务处理完成之后的返回值。

Object ret = pjp.proceed();

log.info("请求结束时间:"+ LocalDateTime.now());

log.info("请求耗时:{}" , (System.currentTimeMillis() - startTime));

// 处理完请求,返回内容

log.info("请求返回 : " , ret);

return ret;

}

```

4、测试结果

```plain

2020-01-13 15:18:21.309 INFO xxx.WebLogAspect : 请求开始时间:2020-01-13T15:18:21.309

2020-01-13 15:18:21.309 INFO xxx.WebLogAspect : 请求Url : http://localhost:8020/api/v1/hourlyStat/findHourlyStatReportList

2020-01-13 15:18:21.320 INFO xxx.WebLogAspect : 请求方式 : POST

2020-01-13 15:18:21.321 INFO xxx.WebLogAspect : 请求ip : 0:0:0:0:0:0:0:1

2020-01-13 15:18:21.322 INFO xxx.WebLogAspect : 请求方法 :

2020-01-13 15:18:21.325 INFO xxx.WebLogAspect : 请求参数 : [HourlyStat{subStrategyId=null}]

2020-01-13 15:18:21.326 INFO xxx.WebLogAspect : 浏览器:CHROME

2020-01-13 15:18:21.327 INFO xxx.WebLogAspect : 浏览器版本:78.0.3904.108

2020-01-13 15:18:21.333 INFO xxx.WebLogAspect : 操作系统: WINDOWS_10

2020-01-13 15:18:21.403 INFO xxx.WebLogAspect : 请求结束时间:2020-01-13T15:18:21.403

2020-01-13 15:18:21.405 INFO xxx.WebLogAspect : 请求耗时:94

2020-01-13 15:18:21.405 INFO xxx.WebLogAspect : 请求返回 : com.soyoung.ad.engine.common.Result@2f935d03

2020-01-13 15:18:21.492 INFO xxx.WebLogAspect : 请求结束时间:2020-01-13T15:18:21.492

2020-01-13 15:18:21.493 INFO xxx.WebLogAspect : 请求耗时:183

2020-01-13 15:18:21.494 INFO xxx.WebLogAspect : 请求返回 : com.soyoung.ad.engine.common.Result@7199e922

2020-01-13 15:18:42.859 INFO xxx.WebLogAspect : 请求开始时间:2020-01-13T15:18:42.859

2020-01-13 15:18:42.860 INFO xxx.WebLogAspect : 请求Url : http://localhost:8020/api/v1/hourlyStat/findHourlyStatReportList

2020-01-13 15:18:42.860 INFO xxx.WebLogAspect : 请求方式 : POST

2020-01-13 15:18:42.861 INFO xxx.WebLogAspect : 请求ip : 0:0:0:0:0:0:0:1

2020-01-13 15:18:42.861 INFO xxx.WebLogAspect : 请求方法 :

2020-01-13 15:18:42.862 INFO xxx.WebLogAspect : 请求参数 : [HourlyStat{subStrategyId=1003}]

2020-01-13 15:18:42.862 INFO xxx.WebLogAspect : 浏览器:CHROME

2020-01-13 15:18:42.863 INFO xxx.WebLogAspect : 浏览器版本:78.0.3904.108

2020-01-13 15:18:42.864 INFO xxx.WebLogAspect : 操作系统: WINDOWS_10

2020-01-13 15:18:42.909 INFO xxx.WebLogAspect : 请求结束时间:2020-01-13T15:18:42.909

2020-01-13 15:18:42.910 INFO xxx.WebLogAspect : 请求耗时:50

2020-01-13 15:18:42.910 INFO xxx.WebLogAspect : 请求返回 : com.soyoung.ad.engine.common.Result@7d494cbd

```

aop springboot 传入参数_java相关:springboot配置aop切面日志打印过程解析相关推荐

  1. java方法设置切点_java相关:Spring AOP中定义切点的实现方法示例

    java相关:Spring AOP中定义切点的实现方法示例 发布于 2020-6-6| 复制链接 摘记: 本文实例讲述了Spring AOP中定义切点的实现方法.分享给大家供大家参考,具体如下:一 配 ...

  2. aop springboot 传入参数_Spring、SpringMVC和SpringBoot看这一篇就够了!

    一.概念 1.Spring Spring是一个开源容器框架,可以接管web层,业务层,dao层,持久层的组件,并且可以配置各种bean,和维护bean与bean之间的关系.其核心就是控制反转(IOC) ...

  3. aop springboot 传入参数_Springboot添加AOP打印请求参数

    1. 引入依赖 org.springframework.boot spring-boot-starter-aop 2. 写切面 切面类需要加@Aspect和@Component注解 package c ...

  4. aop springboot 传入参数_springboot用aop做参数校验

    /** * Created by 12274 on 2018/8/29. * 实现类所有方法入参校验 */ @Aspect @Component @Slf4j public class AopServ ...

  5. java -jar vm参数_java相关:运行jar程序时添加vm参数的方法

    java相关:运行jar程序时添加vm参数的方法 发布于 2020-3-15| 复制链接 下面小妖就为大家带来一篇运行jar程序时添加vm参数的方法.小妖觉得挺不错的,现在就分享给大家,也给大家做个参 ...

  6. java 传入参数_java参数怎么传递参数

    计算机语言给子程序传递参数的方法有两种: 按值传递(call-by-value):这种方法将一个参数值复制成子程序的正式参数.这样,对子程序的参数的改变不影响调用它的参数. 引用调用(call-by- ...

  7. java 传入参数_Java 中方法参数的传递

    java中方法参数传递看似有两种,值传递和引用传递.而实际上都是值传递. 所谓值传递,传递的是变量的副本就是说,在将变量a作为参数传进方法中时,方法中接收到的是a的副本,在方法中对参数的修改实际上修改 ...

  8. java map传入参数_JAVA中map中参数的添加修改

    Map以按键/数值对的形式存储数据,和数组非常相似,在数组中存在的索引,它们本身也是对象. Map的接口 Map---实现Map Map.Entry--Map的内部类,描述Map中的按键/数值对. S ...

  9. spring事务管理-xml配置aop事务(重点)

    刚才咱们是使用了模板操作咱们事务,当然使用模板操作比较low,还得写代码,每个方法都写太费劲了,首先把之前写的先注释掉,把这个transfer这个代码直接复制一份,然后底下展一份,留着注释掉就行了,上 ...

最新文章

  1. [Python]--爬虫 Resources Collection
  2. Tomcat管理平台
  3. “德国屈臣氏”来天猫!欧洲3000家门店,优质低价背后有啥秘密
  4. ASCII码八、十、十六进制对照表
  5. DOM(document object model),文档对象模型
  6. ubunt11 安装mysql_ubuntu 11.10安装mysql
  7. pip install 时报错 ERROR: Could not install packages due to an EnvironmentError: [WinError 5] 拒绝访问(已解决)
  8. java 1是flase_Java这段代码为什么会返回 false?传入的是字符串[1,1]
  9. 高效 保活长连接:手把手教你实现 自适应的心跳保活机制
  10. JavaEE学习--javascript中的正则表达式
  11. 二叉树的遍历方法总结与c++实现
  12. 里诺全系列注册机+暗桩patch
  13. 基于OMAPL138/C6748 + SPARTAN-6 77GHz汽车防撞雷达信号处理平台设计
  14. 微信订阅消息模板消息推送-JAVA
  15. android 带箭头的框,带有工具提示箭头的Android PopupWindow
  16. 统计检验方法 大全,t -test 检验,Anova 检验,卡方检验,Kolmogorov–Smirnov 检验
  17. 要有遥不可及的梦想,也要有脚踏实地的本事
  18. python实践输出星星_打印星星 - Python
  19. 递归函数的简单应用-第五个学生的年龄
  20. ji计算机内存不足怎么回事,Win7提示内存不足的原因及应对措施

热门文章

  1. Bootstrap3 排版-缩略语
  2. 微信支付-接收返回通知结果
  3. 找对业务G点, 体验酸爽 - PostgreSQL内核扩展指南
  4. PHP-Ajax跨域解决方案
  5. .NET项目修改文件夹
  6. java XmlDocument
  7. 嵌入式面试C语言试题
  8. abaqus推荐用哪一版本的_2020年双十一哪一款立式空调/柜式空调值得推荐?【立式空调推荐/柜式空调推荐】·精选...
  9. js 包含某个字符串_[译] 5 大 JavaScript 字符串操作库
  10. java 取得textfield_怎样获取java中textfield的内容