Springboot 如何使用 Aspect 来实现切面日志
作者:飞不起来的童年
- 2021 年 12 月 23 日
本文字数:2710 字
阅读完需:约 9 分钟
以系统日志为例
首先,我们先做一些准备工作。
1、新建一个 Springboot 工程
2、添加必要的依赖
AOP 必须
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency>
复制代码
gson 主要是我用于数据的处理,不是必须的
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.1</version></dependency>
复制代码
个人喜好
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope></dependency><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional></dependency>
复制代码
3、日志实体类和 service
package com.space.aspect.bo; import lombok.Data; /** * 系统日志bo * @author zhuzhe */@Datapublic class SysLogBO { private String className; private String methodName; private String params; private Long exeuTime; private String remark; private String createDate;}
复制代码
package com.space.aspect.service; import com.space.aspect.bo.SysLogBO;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Service; /** * @author zhuzhe */@Slf4j@Servicepublic class SysLogService { public boolean save(SysLogBO sysLogBO){ // 这里就不做具体实现了 log.info(sysLogBO.getParams()); return true; }}
复制代码
4、定义日志注解
这里呢,我们记录日志使用注解的形式。所以,先定义一个注解
package com.space.aspect.anno; import java.lang.annotation.*; /** * 定义系统日志注解 * @author zhuzhe */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface SysLog { String value() default "";}
复制代码
5、声明切面,完成日志记录
以上 4 点我们的准备工作已经完成。接java培训下来就是重点了
这里需要你对 AOP 有一定的了解。起码知道切点表达式、环绕通知、前置通知、后置通知等。。。
package com.space.aspect.aspect; import com.google.gson.Gson;import com.space.aspect.anno.SysLog;import com.space.aspect.bo.SysLogBO;import com.space.aspect.service.SysLogService;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.aspectj.lang.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component; import java.lang.reflect.Method;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List; /** * 系统日志切面 * @author zhuzhe */@Aspect // 使用@Aspect注解声明一个切面@Componentpublic class SysLogAspect { @Autowired private SysLogService sysLogService; /** * 这里我们使用注解的形式 * 当然,我们也可以通过切点表达式直接指定需要拦截的package,需要拦截的class 以及 method * 切点表达式: execution(...) */ @Pointcut("@annotation(com.space.aspect.anno.SysLog)") public void logPointCut() {} /** * 环绕通知 @Around , 当然也可以使用 @Before (前置通知) @After (后置通知) * @param point * @return * @throws Throwable */ @Around("logPointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { long beginTime = System.currentTimeMillis(); Object result = point.proceed(); long time = System.currentTimeMillis() - beginTime; try { saveLog(point, time); } catch (Exception e) { } return result; } /** * 保存日志 * @param joinPoint * @param time */ private void saveLog(ProceedingJoinPoint joinPoint, long time) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); SysLogBO sysLogBO = new SysLogBO(); sysLogBO.setExeuTime(time); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); sysLogBO.setCreateDate(dateFormat.format(new Date())); SysLog sysLog = method.getAnnotation(SysLog.class); if(sysLog != null){ //注解上的描述 sysLogBO.setRemark(sysLog.value()); } //请求的 类名、方法名 String className = joinPoint.getTarget().getClass().getName(); String methodName = signature.getName(); sysLogBO.setClassName(className); sysLogBO.setMethodName(methodName); //请求的参数 Object[] args = joinPoint.getArgs(); try{ List<String> list = new ArrayList<String>(); for (Object o : args) { list.add(new Gson().toJson(o)); } sysLogBO.setParams(list.toString()); }catch (Exception e){ } sysLogService.save(sysLogBO); }}
复制代码
6、测试
接下来,我们就来测试一下吧
package com.space.aspect.controller; import com.space.aspect.anno.SysLog;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController; /** * @author zhuzhe */@RestControllerpublic class TestController { @SysLog("测试") @GetMapping("/test") public String test(@RequestParam("name") String name){ return name; }}
复制代码
启动项目,访问我们的 test 方法。
我们在 service 里打一个断点
可以看到,我们所需要的值都成功拿到了。
这样,我们就成功实现了使用 Aspect 实现切面记录日志。
转自 Java 笔记虾
划线
评论
复制
发布于: 6 小时前阅读数: 73
飞不起来的童年
关注
关注尚硅谷,轻松学IT 2021.11.23 加入
还未添加个人简介











评论