SpringBoot下使用AOP做日志

AOP实现接口执行时间的计算:

  • SpringBoot项目导入spring-boot-starter-aop依赖
  • 编写切面类

  • 类上加@Aspect注解,表明这是一个切面类

  • 类上加@Component,把切面交给Spring管理(我们要切的Controller/Service都是Spring容器的,切面要对它们起作用,就必须同样进入容器)
  • 类内部配置切点表达式,比如@Pointcut (“execution( com.bravo.demo.controller..*(..))”) 表示对com.bravo.demo.controller 包下所有方法进行增强
  • 类内部编写增强逻辑,通常使用@Before、@Around声明这是一个增强,不同的注解增强的方式不同,比如@Before前置增强、@Around环绕增强

1、导入AOP整合SpringBoot依赖

csharp;gutter:true; org.springframework.boot spring-boot-starter-aop</p> <pre><code> > 2、编写切面类:com.zhixi.config.aop.ApiTimeLogAspect ;gutter:true;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
* @ClassName ApiTimeLogAspect
* @Author zhangzhixi
* @Description
* @Date 2022-4-15 10:42
* @Version 1.0
*/
@Slf4j
/*第一步:声明这是一个切面类*/
@Aspect
@Component
public class ApiTimeLogAspect {

/**
* 第二步:定义切点表达式,明确要对那些方法起作用(比如,只对com.bravo.demo.controller包的方法计算接口耗时)
*/
@Pointcut("execution(* com.zhixi.controller.*.*(..))")
public void controllerPointcut() {
}

/**
* 第三步:1.通过引用切点表达式,明确这个增强的应用规则。 2.编写增强逻辑
*
* @param proceedingJoinPoint 执行目标方法的参数
* @return 返回目标方法的执行结果
* @throws Throwable proceedingJoinPoint.proceed()方法抛出的异常
*/
@Around(value = "controllerPointcut()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
// 记录接口执行前的时间戳
long startTime = System.currentTimeMillis();
// 实际执行目标方法,类似动态代理的invoke()执行目标方法
Object result = proceedingJoinPoint.proceed();
// 计算接口耗时
log.info("———— 耗时: {} ms ————", System.currentTimeMillis() – startTime);
// 只做增强不做改变,还是要把接口原本的结果返回
return result;
}
}

3、启动项目访问接口即可

SpringBoot下使用AOP做日志

AOP获取请求的浏览器信息

1、依赖

csharp;gutter:true; org.projectlombok lombok</p> <pre><code> com.alibaba fastjson 1.2.73 eu.bitwalker UserAgentUtils 1.21 org.springframework.boot spring-boot-starter-aop org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test </code></pre> <pre><code> > 2、工具类(对上一版进行了优化) ;gutter:true;
package com.zhixi.util;

import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import eu.bitwalker.useragentutils.Version;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class IpAndAddrUtil {
private static final String UNKNOWN = "unknown";
private static final String[] PROXY_HEADERS = {"x-forwarded-for", "Proxy-Client-IP", "WL-Proxy-Client-IP"};

/**
* 获取发起请求的IP地址
*/
public static String getIp(HttpServletRequest request) {
String ip = null;
for (String header : PROXY_HEADERS) {
ip = request.getHeader(header);
if (ip != null && ip.length() != 0 && !UNKNOWN.equalsIgnoreCase(ip)) {
break;
}
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if ("127.0.0.1".equals(ip)) {
try {
ip = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
if (ip != null && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
return ip;
}

/**
* 获取发起请求的浏览器名称
*/
public static String getBrowserName(HttpServletRequest request) {
UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
Browser browser = userAgent.getBrowser();
return browser.getName();
}

/**
* 获取发起请求的浏览器版本号
*/
public static String getBrowserVersion(HttpServletRequest request) {
UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
Browser browser = userAgent.getBrowser();
Version version = browser.getVersion(request.getHeader("User-Agent"));
return version == null ? null : version.getVersion();
}

/**
* 获取发起请求的操作系统名称
*/
public static String getOsName(HttpServletRequest request) {
UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
OperatingSystem os = userAgent.getOperatingSystem();
return os.getName();
}
}

3、AOP:前置通知

csharp;gutter:true; package com.zhixi.aop;</p> <p>import com.alibaba.fastjson.JSONObject; import com.zhixi.util.IpAndAddrUtil; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;</p> <p>import javax.servlet.http.HttpServletRequest;</p> <p>@Aspect @Component @Slf4j public class LogBrowserAspect {</p> <pre><code>@Pointcut("execution(* com.zhixi.controller.*.*(..))") public void webLog() { } @Before("webLog()") public void doBefore(JoinPoint joinPoint) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); assert attributes != null; HttpServletRequest request = attributes.getRequest(); /*获取请求IP*/ String requestIp = IpAndAddrUtil.getIp(request); /*获取发起请求的浏览器版本号*/ String browserVersion = IpAndAddrUtil.getBrowserVersion(request); /*获取发起请求的操作系统名称*/ String osName = IpAndAddrUtil.getOsName(request); /*获取发起请求的浏览器名称*/ String browserName = IpAndAddrUtil.getBrowserName(request); JSONObject jsonObject = new JSONObject(); jsonObject.put("requestURL", request.getRequestURL()); jsonObject.put("ip", requestIp); jsonObject.put("browserVersion", browserVersion); jsonObject.put("osName", osName); jsonObject.put("browserName", browserName); jsonObject.forEach((k, v) -> { log.info(k + ":" + v); }); } </code></pre> <p>}

4、测试

SpringBoot下使用AOP做日志

Original: https://www.cnblogs.com/zhangzhixi/p/16150607.html
Author: Java小白的搬砖路
Title: SpringBoot下使用AOP做日志

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/575278/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • [Java] Hashtable 源码简要分析

    线程安全。 Key、Value均不能为null。 包含了一个Entry[]数组,而Entry又是一个链表,用来处理冲突。 每个Key对应了Entry数组中固定的位置(记为index…

    Java 2023年5月29日
    0101
  • maven的安装和仓库的种类和彼此关系

    Maven软件的下载 为了使用Maven管理工具,哦我们首先要到官网去下载他的安装软件,通过百度搜索Mav嗯如下: 点击Download连接,就可以直接进入到Maven软件的下载页…

    Java 2023年6月6日
    090
  • java宝典笔记2

    一、java 程序初始化的顺序是怎样的 父类静态变量、父类静态代码块、(父类也叫超类) 子类静态变量、子类静态代码块、 父类非静态变量、父类非静态代码块、父类构造函数、 子类非静态…

    Java 2023年6月7日
    070
  • Java函数的学习

    函数的定义 – &#x5B9A;&#x4E49;&#x7684;&#x4F4D;&#x7F6E;&#xFF1A;&#x5B9…

    Java 2023年6月5日
    068
  • 约瑟夫环问题(C语言)

    单链表实现约瑟夫环问题 约瑟夫环 这里建议使用 循环单链表 代码实现(c语言) #include #include typedef struct node{ int data; s…

    Java 2023年6月5日
    083
  • 六、面向对象编程

    一、什么是类?什么是对象? 类:具有共同特征的描述 对象:真实存在的具体事例 二、对象的内存图: 两个变量指向同一个对象内存图 三、构造器 就是无参构造方法和有参构造方法 四、th…

    Java 2023年6月6日
    091
  • 备忘录--关于线程和IO知识

    因为自己还在出差中,没时间深入学习,最近工作里又有对一些技术的思考,所以这里记录下来,等回去有时间可以按照这个思路进行学习,这里主要起到备忘的作用。 1.线程难学难在我们没有理解操…

    Java 2023年5月30日
    052
  • get,post,put,delete四种基础方法对应增删改查

    PUT,DELETE,POST,GET四种基础方法对应增删改查 1、 GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的 select操作一样,只是用来 查询…

    Java 2023年6月15日
    097
  • 数据视图

    视图作用 定义视图是设计数据库外模式的基本手段。视图能够为数据库系统提供一下优势: 1. &#x6570;&#x636E;&#x7684;&#x90…

    Java 2023年6月9日
    087
  • MongoDB安装使用教程

    MongoDB安装使用教程 介绍 MongoDB是一个基于分布式文件存储的数据库,是一个文档数据库,支持的数据结构非常松散,是类似json的bson格式,可以存储比较复杂的数据类型…

    Java 2023年6月15日
    088
  • Lamda(拉姆达)表达式演化过程

    HI!小伙伴们,好久没见了,4月份开始断更,中途有点事儿,今天开始更新了,整理一篇Lamda表达式演化过程,希望喜欢的一如既往的支持! 传统集合过滤 现在有2个需求:在一组学生集合…

    Java 2023年6月8日
    071
  • JAVA中int转string及String.valueOf()的使用

    日常java开放中,经常会遇到int和String的互转,一般图省事的做法就是: 1 String length = ""+100; length的生成需要使用…

    Java 2023年6月6日
    082
  • 待学习

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月6日
    084
  • 一文理解Hadoop分布式存储和计算框架入门基础

    @ 概述 定义 发展历史 发行版本 优势 生态项目 架构 组成模块 HDFS架构 YARN架构 部署 部署规划 前置条件 部署步骤 下载文件(三台都执行) 创建目录(三台都执行) …

    Java 2023年6月5日
    073
  • JavaCV推流实战(MP4文件)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kuberne…

    Java 2023年6月8日
    095
  • 程序员最容易读错的单词,听到status我炸了

    最近在跟同事讨论问题的时候,他突然对我说。。。 这个 死太丢死不太对,需要改一下。。。 我当时应该是愣住了,然后想了一下,你说的是 status 吗??? 看着他疑惑不解的眼神,我…

    Java 2023年6月13日
    072
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球