🧑💻作者名称:DaenCode
🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。
😎人生感悟:尝尽人生百味,方知世间冷暖。
📖所属专栏:SpringBoot实战
系列文章目录
标题 |
---|
一文带你学会使用SpringBoot+Avue实现短信通知功能(含重要文件代码) |
一张思维导图带你学会Springboot创建全局异常、自定义异常 |
一张思维导图带你打通SpringBoot自定义拦截器的思路 |
28个SpringBoot项目中常用注解,日常开发、求职面试不再懵圈 |
一张思维导图带你学会SpringBoot、Vue前后端分离项目线上部署 |
一张思维导图带你学会使用SpringBoot中的Schedule定时发送邮件 |
一张思维导图带你学会使用SpringBoot异步任务实现下单校验库存 |
思维导图
🌟AOP介绍
基本概念:在不改变原有功能的逻辑,增加新的功能。
应用场景:
- 权限控制
- 日志处理
- 事务控制
下面以对产品数据增删改查功能,进行日志管理功能为例,对AOP中的核心概念作出介绍,请参考下表
概念 | 解析 | 对应日志管理功能 |
---|---|---|
核心关注点 | 业务逻辑的主要功能,应用程序主要关注的部分 | 产品数据的增删改查 |
横切关注点 | 与核心关注点相关但不属于核心关注点的功能,在系统的多个模块或组件中散布 | 记录产品操作的日志 |
通知 | 在特定切入点执行时要执行的代码,实现横切关注点的具体逻辑。可以在目标方法执行之前、之后或抛出异常时执行 | 执行记录日志的代码 |
连接点 | 可以插入通知的特定点,通常是方法执行的位置 | 产品表操作的方法 |
切入点 | 通过表达式或规则定义的连接点的集合。确定了哪些连接点与通知关联起来 | 选择所有的插入、更新或删除操作的连接点集合 |
切面 | 横切关注点和通知的组合,将通知应用到切入点匹配的连接点上 | 包含记录日志的通知和定义切入点的规则 |
目标 | 被通知的对象或类,即应用程序中执行具体操作的对象或方法 | 对产品数据作出操作的对象或方法 |
织入 | 将切面应用到目标对象上,创建新的代理对象的过程。可以在编译时、加载时或运行时进行 | 将日志管理切面应用到产品表操作的目标对象上,以记录日志 |
🌟具体实现步骤
数据准备
创建产品表、以及日志表,并向产品表添加相关数据。
CREATE TABLE `product` (
`id` int(11) NOT NULL,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`price` decimal(10, 2) NULL DEFAULT NULL,
`stock` int(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
-- ----------------------------
-- Records of product
-- ----------------------------
INSERT INTO `product` VALUES (1, '苹果13', 10.99, 50);
INSERT INTO `product` VALUES (2, '小米10', 19.99, 99);
INSERT INTO `product` VALUES (3, '华为mate20', 5.99, 19);
CREATE TABLE `log` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`operation` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`data` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`operate_time` datetime NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
引入相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
创建实体类
Product类
public class Product implements Serializable {
private Integer id;
private String name;
private BigDecimal price;
private Integer stock;
}
Log类
public class Log implements Serializable {
private Integer id;
private String operation;
private String data;
private Timestamp operateTime;
}
自定义注解@LogTip
自定义注解,用于标记记录日志的方法。
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogTip {
String value() default "";
}
定义切面类
切面类由切点PointCut+通知Advice
共同构成。有关于通知的类型以及解释,可以查看思维导图中的通知节点
。有关于JoinPoint的API见下表
API | 描述 |
---|---|
getSignature() | 获取连接点的签名,返回一个MethodSignature对象 |
getArgs() | 获取连接点方法的参数数组 |
getTarget() | 获取目标对象 |
getThis() | 获取当前代理对象 |
toShortString() | 生成连接点的简短描述 |
toLongString() | 生成连接点的详细描述 |
getStaticPart() | 获取静态连接点部分 |
getKind() | 获取连接点的类型 |
getSourceLocation() | 获取连接点所在位置的源代码位置 |
@Component
@Aspect
public class LogAspect {
@Autowired
private LogMapper logMapper;
@Pointcut("@annotation(com.shoanjen.redis.annotation.LogTip)")
public void pointCut(){}
@AfterReturning("pointCut()")
public void getLogInfo(JoinPoint point) throws Throwable {
// 获取方法参数列表
Object[] args = point.getArgs();
//获取自定义注解上的描述信息
MethodSignature methodSignature= (MethodSignature) point.getSignature();
Method method=methodSignature.getMethod();
LogTip annotation=method.getAnnotation(LogTip.class);
String desc=annotation.value();
// 获取操作的数据
String data = Arrays.toString(args);
// 记录日志
saveLog(desc, data);
}
private void saveLog(String desc, String data) {
Log log = new Log();
log.setOperation(desc);
log.setData(data);
log.setOperateTime(new Timestamp(System.currentTimeMillis()));
logMapper.save(log);
}
}
LogMapper
public interface LogMapper {
void save(Log log);
}
<insert id="save" parameterType="com.shoanjen.redis.model.Log" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
INSERT INTO log(operation, data, operate_time) VALUES (#{operation}, #{data}, #{operateTime});
</insert>
ProductController
这里以上一篇文章一张思维导图带你学会使用SpringBoot异步任务实现下单校验库存中的产品下单功能为例子,对其记录日志。
@RestController
@RequestMapping("/api/v1/product")
public class ProductController {
@Autowired
private ProductService productService;
@Autowired
private ValidateTask validateTask;
@LogTip("产品下单")
@RequestMapping("order")
public JsonData order(@RequestParam int productId,@RequestParam int quantity) throws ExecutionException, InterruptedException {
Future<Boolean> validateResult=validateTask.validateStock(productId,quantity);
System.out.println(validateResult.get());
Boolean flag=false;
//判断异步任务是否完成
if (validateResult.isDone()){
try {
flag=validateResult.get();
} catch (Exception e) {
flag=false;
}
}
if (flag){
return JsonData.buildSuccess("下单成功");
}else {
return JsonData.buildError("下单失败,库存不足");
}
}
}
🌟最终测试
接口请求测试
日志表查看
🌟写在最后
有关于SpringBoot使用AOP实现日志管理功能到此就结束了。感谢大家的阅读,希望大家在评论区对此部分内容散发讨论,便于学到更多的知识。文章来源:https://www.toymoban.com/news/detail-643441.html
文章来源地址https://www.toymoban.com/news/detail-643441.html
到了这里,关于一张思维导图带你学会SpringBoot使用AOP实现日志管理功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!