前言

请问今天您便秘了吗?程序员坐久了真的会便秘哦,如果偶然点进了这篇小干货,就麻烦您喝杯水然后去趟厕所一边用左手托起对准嘘嘘,一边用右手滑动手机看完本篇吧。

实现

本篇AOP统一日志管理写法来源于国外知名开源框架JHipster的AOP日志管理方式

1、引入依赖

<!-- spring aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2、定义logback配置

1)、dev、test环境的spring-web包定义日志级别为INFO,项目包定义日志级别为DEBUG;

2)、prod环境的spring-web包定义日志级别为ERROR,项目包定义日志级别为INFO;

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.springframework.web" level="INFO"/>
<logger name="org.springboot.sample" level="TRACE" /> <springProfile name="dev,test">
<logger name="org.springframework.web" level="INFO"/>
<logger name="org.springboot.sample" level="INFO" />
<logger name="com.example.aoplog" level="DEBUG" />
</springProfile> <springProfile name="prod">
<logger name="org.springframework.web" level="ERROR"/>
<logger name="org.springboot.sample" level="ERROR" />
<logger name="com.example.aoplog" level="INFO" />
</springProfile> </configuration>

3、编写切面类

1)、springBeanPointcut():单独定义的spring框架切入点;

2)、applicationPackagePointcut():单独定义的项目包切入点;

3)、logAfterThrowing():1和2定义的切入点抛出异常时日志格式及显示内容;

4)、logAround():1和2定义的切入点方法进入和退出时日志格式及显示内容。

package com.example.aoplog.logging;

import com.example.aoplog.constants.GloablConstants;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.stereotype.Component; import java.util.Arrays; /**
* <p>
* AOP统一日志管理 切面类
* </p>
*
* @author 福隆苑居士,公众号:【Java分享客栈】
* @since 2022/5/5 21:57
*/
@Aspect
@Component
public class LoggingAspect { private final Logger log = LoggerFactory.getLogger(this.getClass()); private final Environment env; public LoggingAspect(Environment env) {
this.env = env;
} /**
* 匹配spring框架的repositories、service、rest端点的切面
*/
@Pointcut("within(@org.springframework.stereotype.Repository *)" +
" || within(@org.springframework.stereotype.Service *)" +
" || within(@org.springframework.web.bind.annotation.RestController *)")
public void springBeanPointcut() {
// 方法为空,因为这只是一个切入点,实现在通知中。
} /**
* 匹配我们自己项目的repositories、service、rest端点的切面
*/
@Pointcut("within(com.example.aoplog.repository..*)"+
" || within(com.example.aoplog.service..*)"+
" || within(com.example.aoplog.controller..*)")
public void applicationPackagePointcut() {
// 方法为空,因为这只是一个切入点,实现在通知中。
} /**
* 记录方法抛出异常的通知
*
* @param joinPoint join point for advice
* @param e exception
*/
@AfterThrowing(pointcut = "applicationPackagePointcut() && springBeanPointcut()", throwing = "e")
public void logAfterThrowing(JoinPoint joinPoint, Throwable e) { // 判断环境,dev、test or prod
if (env.acceptsProfiles(Profiles.of(GloablConstants.SPRING_PROFILE_DEVELOPMENT, GloablConstants.SPRING_PROFILE_TEST))) {
log.error("Exception in {}.{}() with cause = '{}' and exception = '{}'", joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(), e.getCause() != null? e.getCause() : "NULL", e.getMessage(), e); } else {
log.error("Exception in {}.{}() with cause = {}", joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(), e.getCause() != null? e.getCause() : "NULL");
} } /**
* 在方法进入和退出时记录日志的通知
*
* @param joinPoint join point for advice
* @return result
* @throws Throwable throws IllegalArgumentException
*/
@Around("applicationPackagePointcut() && springBeanPointcut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { if (log.isDebugEnabled()) {
log.debug("Enter: {}.{}() with argument[s] = {}", joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs()));
}
try {
Object result = joinPoint.proceed();
if (log.isDebugEnabled()) {
log.debug("Exit: {}.{}() with result = {}", joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(), result);
}
return result;
} catch (IllegalArgumentException e) {
log.error("Illegal argument: {} in {}.{}()", Arrays.toString(joinPoint.getArgs()),
joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName()); throw e;
} } }

4、测试

1)、写个service

package com.example.aoplog.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; /**
* <p>
* AOP统一日志管理测试服务
* </p>
*
* @author 福隆苑居士,公众号:【Java分享客栈】
* @since 2022/5/5 21:57
*/
@Service
@Slf4j
public class AopLogService { public String test(Integer id) {
return "传入的参数是:" + id;
}
}

2)、写个controller

package com.example.aoplog.controller;

import com.example.aoplog.service.AopLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; /**
* <p>
* 测试接口
* </p>
*
* @author 福隆苑居士,公众号:【Java分享客栈】
* @since 2022/4/30 11:43
*/
@RestController
@RequestMapping("/api")
@Slf4j
public class TestController { private final AopLogService aopLogService; public TestController(AopLogService aopLogService) {
this.aopLogService = aopLogService;
} @GetMapping("/test/{id}")
public ResponseEntity<String> test(@PathVariable("id") Integer id) {
return ResponseEntity.ok().body(aopLogService.test(id));
}
}

3)、设置环境

这里我试试dev,prod自己试听见没?不服一拳打哭你哦!

server:
port: 8888 # 环境:dev-开发 test-测试 prod-生产
spring:
profiles:
active: dev

4)、效果

不解释了自己看

试试异常情况,手动加个异常。

@Service
@Slf4j
public class AopLogService { public String test(Integer id) {
int i = 1/0;
return "传入的参数是:" + id;
}
}

效果

总结

OK!打完收工!

链接:https://pan.baidu.com/doc/share/flr0QYwZYPYxmWSRPbnJRw-1028798558141759

提取码:bxaa


记住,别点赞,别推荐,别关注 ,好好上个厕所喝杯水,你们今天下班前能拉出来我就心满意足了。

【Java分享客栈】超简洁SpringBoot使用AOP统一日志管理-纯干货干到便秘的更多相关文章

  1. 【Java分享客栈】SpringBoot整合WebSocket+Stomp搭建群聊项目

    前言 前两周经常有大学生小伙伴私信给我,问我可否有偿提供毕设帮助,我说暂时没有这个打算,因为工作实在太忙,现阶段无法投入到这样的领域内,其中有两个小伙伴又问到我websocket该怎么使用,想给自己的 ...

  2. 【Java分享客栈】SpringBoot线程池参数搜一堆资料还是不会配,我花一天测试换你此生明白。

    一.前言   首先说一句,如果比较忙顺路点进来的,可以先收藏,有时间或用到了再看也行:   我相信很多人会有一个困惑,这个困惑和我之前一样,就是线程池这个玩意儿,感觉很高大上,用起来很fashion, ...

  3. SpringBoot学习笔记(七):SpringBoot使用AOP统一处理请求日志、SpringBoot定时任务@Scheduled、SpringBoot异步调用Async、自定义参数

    SpringBoot使用AOP统一处理请求日志 这里就提到了我们Spring当中的AOP,也就是面向切面编程,今天我们使用AOP去对我们的所有请求进行一个统一处理.首先在pom.xml中引入我们需要的 ...

  4. 【Java分享客栈】我为什么极力推荐XXL-JOB作为中小厂的分布式任务调度平台

    前言   大家好,我是福隆苑居士,今天给大家聊聊XXL-JOB的使用.   XXL-JOB是本人呆过的三家公司都使用到的分布式任务调度平台,前两家都是服务于传统行业(某大型移动基地和某大型电网),现在 ...

  5. 【Java分享客栈】一文搞定京东零售开源的AsyncTool,彻底解决异步编排问题。

    一.前言 本章主要是承接上一篇讲CompletableFuture的文章,想了解的可以先去看看案例: https://juejin.cn/post/7091132240574283813 Comple ...

  6. 【Java分享客栈】一文搞定CompletableFuture并行处理,成倍缩短查询时间。

    前言   工作中你可能会遇到很多这样的场景,一个接口,要从其他几个service调用查询方法,分别获取到需要的值之后再封装数据返回.   还可能在微服务中遇到类似的情况,某个服务的接口,要使用好几次f ...

  7. Spring MVC 中使用AOP 进行统一日志管理--XML配置实现

    1.介绍 上一篇博客写了使用AOP进行统一日志管理的注解版实现,今天写一下使用XML配置实现版本,与上篇不同的是上次我们记录的Controller层日志,这次我们记录的是Service层的日志.使用的 ...

  8. [置顶] 使用sping AOP 操作日志管理

    记录后台操作人员的登陆.退出.进入了哪个界面.增加.删除.修改等操作 在数据库中建立一张SYSLOG表,使用Sping 的AOP实现日志管理,在Sping.xml中配置 <!-- Spring ...

  9. Spring Boot 入门(五):集成 AOP 进行日志管理

    本篇文章是接着 Spring boot 入门(四):集成 Shiro 实现登陆认证和权限管理写的,按照前面几篇博客的教程,可以搭建一个简单的项目,主要包含了 Pagehelper+MyBatis 分页 ...

随机推荐

  1. 学习Apache(三)

    对某个目录开启验证登录 <Directory /var/www/html/admin > AllowOverride All Order allow,deny Allow from all ...

  2. npm run start 后台运行

    yum provides */nohup nohup npm start & 原程序的的标准输出被自动改向到当前目录下的nohup.out文件,起到了log的作用. 停止程序   ps -ef ...

  3. idea常见设置一

    1.顶部执行栏调整 原: 设置:勾选view==>toolbar 后: 这个一看其实没有什么太大的作用,但是你看这个按钮 这个按钮就是File==>Settings,这样会稍微方便点,只要 ...

  4. 超声波模块HC-SR04简介以及编程

    HC-SR04 一.主要参数1:使用电压:DC-5V2:静态电流:小于2mA3:电平输出:高5V4:电平输出:底0V5:感应角度:不大于15度6:探测距离:2cm-450cm7:高精度 可达0.2cm ...

  5. 浏览器中唤起native app || 跳转到应用商城下载

    前段时间遇到一个小需求:要求在分享出来的h5页面中,有一个立即打开的按钮,如果本地安装了我们的app,那么点击就直接唤起本地app,如果没有安装,则跳转到下载. 因为从来没有做过这个需求,因此这注定是 ...

  6. Episode 1:正视微信(试播)

    本期是 WEB VIEW 的第一期播客节目. 「不囿于 WEB,不止于 VIEW」,WEB VIEW 是由 yin 和敬礼主持的一档泛科技播客.节目中我们谨慎考量技术进步所带来的优缺点,提倡用「人治」 ...

  7. 一个动态波浪纹Android界面

    IndexActivity.java package com.example.rubikrobot; import androidx.appcompat.app.AppCompatActivity; ...

  8. 安卓性能测试之 adb shell 常用命令

    pm list packages 列出包名adb shell pm list packages:列出所有的包名.adb shell dumpsys package:列出所有的安装应用的信息adb sh ...

  9. idea 创建maven web项目部署在 tomcat maven plugin中

    前提:1.安装jdk,多数系统使用jdk1.8.xxx,因此选择下载此版本的居多 2.安装Maven 3.部署到tomcat我们可以有两种方式,一种是利用tomcat插件来进行部署,另一种是下载tom ...

  10. leetcode多线程题目

    代码附上了力扣没显示出来的测试 按序打印 class Foo { private CountDownLatch latch = new CountDownLatch(1); private Count ...