56_AOP
AOP使用案例
如何进行数据库和Redis中的数据同步?/ 你在项目的那些地方使用了aop?
答:可以通过Aop操作来实现数据库和Redis中的数据同步。/ 通过Aop操作来实现数据库和Redis中的数据同步。
可以定义一个切面类,通过对控制器下的所有方法进行环绕通知。
数据同步有两种情况
- 一种是服务器接收get请求,首先从Redis中取,没有对应的key再执行方法从数据库中获取数据并添加到Redis中;
- 第二种情况是服务器接收写请求,包括增删改,这时就需要先对Redis中的数据进行扫描,对特定key对应的的数据进行删除清空,再执行方法修改数据库中的内容(没有考虑再次将数据库中的数据同步到Redis是因为:如果服务器接收到任一get请求,都会自动进行同步)
import cn.cnmd.redis.RedisService;
import com.alibaba.fastjson2.JSON;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
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 org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;import java.lang.reflect.Method;
import java.time.Duration;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;@Aspect
@Component
public class RedisCacheAspect {private static Random random = new Random();@Autowiredprivate RedisService redisService;@Pointcut("execution(* cn.ctmd.electric.*.controller.*(..))")private void pointcut() {}@Around("pointcut()")public Object around(ProceedingJoinPoint pjp) throws Throwable {Signature signature = pjp.getSignature();MethodSignature methodSignature = (MethodSignature) signature;Method method = methodSignature.getMethod();String className = method.getDeclaringClass().getSimpleName();String methodName = method.getName();if (method.isAnnotationPresent(GetMapping.class)) {// get请求Object[] args = pjp.getArgs();String cacheKey = className + "::" + methodName + JSON.toJSONString(args);if (Boolean.TRUE.equals(redisService.hasKey(cacheKey))) {return redisService.get(cacheKey);} else {synchronized (this) {if (Boolean.FALSE.equals(redisService.hasKey(cacheKey))) {Object value = pjp.proceed();long expireTime = Duration.ofMinutes(5).toMillis() + random.nextInt(1000);redisService.set(cacheKey, value, expireTime, TimeUnit.MILLISECONDS);return value;} else {return redisService.get(cacheKey);}}}} else {if (method.isAnnotationPresent(PostMapping.class) || method.isAnnotationPresent(PutMapping.class) || method.isAnnotationPresent(DeleteMapping.class)) {List<String> list = redisService.scan(className, 50);if (list != null) {redisService.delete(list.toString());}}}return pjp.proceed();}
}
AOP
概念:面向切面编程
术语
- 连接点:被拦截到的程序的执行点(在spring中就是被拦截到的方法)
- 切入点:对需要进行拦截的条件的定义(某个位置)
- 通知、增强:为切入点添加二维的功能
- 目标对象:要被增强的对象
- 织入:将切面和业务逻辑对象连接起来,并创建通知代理的过程
- 代理:被织入后产生的结果类
- 切面:一个横切关注点的模块化(一个切面类的代称)
类型
- 前置通知
- 后置通知
- 环绕通知
- 异常抛出通知
- 最终通知(少见)
一个切面类
@Aspect
public class AspectJAdvice {@Before(value = "execution(* com.qf.spring.aop.service..*(..))")public void before(JoinPoint jp){Object[] args = jp.getArgs(); //获取方法参数Signature signature = jp.getSignature(); //获取签名if(signature instanceof MethodSignature){ //如果签名是方法签名Method method = ((MethodSignature) signature).getMethod(); //获取方法String methodName = method.getName();String className = method.getDeclaringClass().getName();System.out.println("准备执行方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args));}}@AfterReturning(value = "execution(* com.qf.spring.aop.service..*(..))", returning = "returnValue")public void after(JoinPoint jp, Object returnValue){Object[] args = jp.getArgs(); //获取方法参数Signature signature = jp.getSignature(); //获取签名if(signature instanceof MethodSignature){ //如果签名是方法签名Method method = ((MethodSignature) signature).getMethod(); //获取方法String methodName = method.getName();String className = method.getDeclaringClass().getName();System.out.println("执行完方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",得到返回值:" + returnValue);}}@AfterThrowing(value = "execution(* com.qf.spring.aop.service..*(..))", throwing = "t")public void exception(JoinPoint jp, Throwable t){Object[] args = jp.getArgs(); //获取方法参数Signature signature = jp.getSignature(); //获取签名if(signature instanceof MethodSignature){ //如果签名是方法签名Method method = ((MethodSignature) signature).getMethod(); //获取方法String methodName = method.getName();String className = method.getDeclaringClass().getName();System.out.println("执行方法时:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",发生了异常:" + t.getMessage());}}@Around("execution(* com.qf.spring.aop.service..*(..))")public Object around(ProceedingJoinPoint pjp) throws Throwable {Object[] args = pjp.getArgs();//获取方法的参数Object target = pjp.getTarget(); //获取代理对象Signature signature = pjp.getSignature(); //获取签名if(signature instanceof MethodSignature) { //如果签名是方法签名Method method = ((MethodSignature) signature).getMethod(); //获取被拦截的方法对象String methodName = method.getName();String className = method.getDeclaringClass().getName();try {System.out.println("准备执行方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args));Object returnValue = method.invoke(target, args);System.out.println("执行完方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",得到返回值:" + returnValue);return returnValue;} catch (Throwable t){System.out.println("执行方法时:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",发生了异常:" + t.getMessage());throw t;}}return null;}
}
相关文章:
56_AOP
AOP使用案例 如何进行数据库和Redis中的数据同步?/ 你在项目的那些地方使用了aop?答:可以通过Aop操作来实现数据库和Redis中的数据同步。/ 通过Aop操作来实现数据库和Redis中的数据同步。可以定义一个切面类,通过对控制器下的所有…...
安装了h5py,使用报错ImportError: DLL load failed while importing _errors
使用pip 安装了h5py,但是运行代码报错; from . import _errorsImportError: DLL load failed while importing _errors: 找不到指定的程序。 原因: 可能和不正确安装h5py这个包有关系 解决: pip uninstall h5py 换成使用conda…...
BootStrap前端面试常见问题
在前端面试中,关于Bootstrap的问题通常围绕其基本概念、使用方式、特性以及实际应用等方面展开。以下是一些常见的问题及其详细解答: 1. Bootstrap是哪家公司研发的? 回答:Bootstrap是由Twitter的Mark Otto和Jacob Thornton合作…...
在linux运维中为什么第一道防线是云防火墙,而不是waf
在Linux运维和云计算环境中,第一道防线通常是云防火墙(Cloud Firewall),而不是Web应用防火墙(WAF),主要是因为云防火墙提供了更基础和广泛的网络层安全控制。以下是一些关键原因: 1…...
2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛
2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 2024.8.2 12:00————16:00 过题数790/1500 补题数943.33/1500 AB Problem Komorebi的数学课 次佛锅 Setsuna的K数列 Wiki下象棋 黄金律法 天气预报 叠硬币 AB Problem ag…...
多语言海外AEON抢单可连单加额外单源码,java版多语言抢单系统
多语言海外AEON抢单可连单加额外单源码,java版多语言抢单系统。此套是全新开发的java版多语言抢单系统。 后端java,用的若依框架,这套代码前后端是编译后的,测试可以正常使用,语言繁体,英文,日…...
文件上传——springboot大文件分片多线程上传功能,前端显示弹出上传进度框
一、项目搭建 创建 Spring Boot 项目: 创建一个新的 Spring Boot 项目,添加 Web 依赖。 添加依赖: 在 pom.xml 文件中添加以下依赖: <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId&…...
每日学术速递8.2
1.A Scalable Quantum Non-local Neural Network for Image Classification 标题: 用于图像分类的可扩展量子非局部神经网络 作者: Sparsh Gupta, Debanjan Konar, Vaneet Aggarwal 文章链接:https://arxiv.org/abs/2407.18906 摘要&#x…...
SAP-PLM创建物料主数据接口
FUNCTION zplm_d_0001_mm01. *"---------------------------------------------------------------------- *"*"本地接口: *" EXPORTING *" VALUE(EX_TOTAL) TYPE CHAR4 *" VALUE(EX_SUCCESSFUL) TYPE CHAR4 *" …...
超声波眼镜清洗机哪个品牌好?四款高性能超声波清洗机测评剖析
对于追求高生活质量的用户来说,眼镜的清洁绝对不能马虎。如果不定期清洁眼镜,时间久了,镜片的缝隙中会积累大量的灰尘和细菌,眼镜靠近眼部,对眼部健康有很大影响。在这种情况下,超声波清洗机显得尤为重要。…...
卸载Windows软件的正确姿势,你做对了吗?
前言 今天有小伙伴突然问我:她把软件都卸载了,但是怎么软件都还在运行? 这个问题估计很多小伙伴都是遇到过的,对于电脑小白来说,卸载Windows软件真的真的真的是一件很难的事情。所以,今天咱们就来讲讲&am…...
WEB前端14-Element UI(学生查询表案例/模糊查询/分页查询)
Vue2-Element UI 1.可重用组件的开发 可重用组件 我们一般将可重复使用的组件放在components目录之下,以便父组件的灵活调用 <!--可重用组件一般与css密切相关,使用可重用组件的目的是,将相似的组件放在一起,方便使用-->…...
使用swiftui自定义圆形进度条实现loading
实现的代码如下: // // LoadingView.swift // SwiftBook // // Created by Song on 2024/8/2. //import SwiftUIstruct LoadingView: View {State var process 0.5var body: some View {VStack(spacing: 20) {ZStack {Circle().stroke(.gray.opacity(0.3), lin…...
C# 设计模式之抽象工厂模式
总目录 前言 工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码,而工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性。但是在现实生活中,…...
Javascript前端面试基础(八)
window.onload和$(document).ready区别 window.onload()方法是必须等到页面内包括图片的所有元素加载完毕后才能执行$(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕 window.onload 触发时机:window.onload 事件会在整个页面…...
R 语言学习教程,从入门到精通,R的安装与环境的配置(2)
1、R的安装与环境的配置 R语言是一款完全免费且开源的软件,它的开源许可证是GNU通用公共许可证(GPL),这意味着任何人都可以自由地使用、复制、修改和发布R语言的源代码,甚至可以将其用于商业用途。 和python等其他语言…...
Python批量下载音乐功能
Python批量下载音乐功能 Python批量下载音乐,调用API接口,同时下载歌曲和歌词 先安排一下要用的模块,导入进来。 import re import json import requests目录结构 下载音乐 Awking_Class.pymusic.txt 文件文件写的是音乐名字,使用换行分割 new_music 注意这个 ne…...
用 Bytebase 实现批量、多环境、多租户数据库的丝滑变更
Bytebase 提供了多种功能来简化批量变更管理,适用于多环境或多租户情况。本教程将指导您如何使用 部署配置 和 数据库组 在不同场景下进行数据库批量变更。 默认流水线 vs 部署配置 图片数据库 vs 数据库组 1. 准备 请确保已安装 Docker,如果本地没有重…...
java之方法引用 —— ::
目录 一、简介 二、引用静态方法 1.格式 2.示例 编辑 3.条件解析 三、引用成员方法 1.格式 2.示例 四、引用构造方法 1.格式 2.示例 五、类名引用成员方法 1.格式 2.略微不同的方法引用规则 3.示例 六、引用数组的构造方法 1.格式 2.示例 一、简介 方…...
「测试线排查的一些经验-上篇」 后端工程师
文章目录 端口占用脚本失灵线上部署项目结构模版配置文件生效 一般产品研发过程所使用的环境可分为: 研发环境-dev测试环境-test生产环境-prod 软件开发中,完整测试环境包括:UT、IT、ST、UAT UT Unit Test 单元测试 IT System Integration …...
AOSP12_BatteryStats统计电池数据信息
前言 BatteryStats模块主要用于设备在电池供电是系统对各个模块电量使用的统计,Android提供的Battery Historain工具就是对此模块统计的数据进行解析和展示。 一 BatteryStats模块类图 模块主要类图如下:见根目录的模块类图 BatteryStats:抽象类,本模块的核心类,主要定…...
【Android Studio】UI 布局
文章目录 view布局LinearLayout view 在Android开发中,View是一个非常重要的概念,它是所有用户界面组件的基类。View类及其子类构成了Android应用中的用户界面。每个View都占用屏幕上的一个矩形区域,并可以响应用户输入(如触摸、按…...
虚拟机Windows server忘记密码解决方法
原理 utilman.exe是Windows辅助工具管理器程序,虽然它本身不是一个关键的系统进程,但通过修改这个文件,用户可以访问一些有用的UI设置。在某些情况下,比如忘记密码需要重置时,通过修改utilman.exe文件为c…...
【香橙派系列教程】(六)嵌入式SQLite数据库
【六】嵌入式SQLite数据库 文章目录 【六】嵌入式SQLite数据库1.简介2.SQLite数据库安装3.SQLite命令用法1.创建数据库2.创建和查看表格3.插入查看数据(记录)4.删除更改数据(记录) 4.SQLite编程操作1.打开/创建数据库的C接口2.创建…...
深入探讨PHP8的新特性与性能优化
本文由 ChatMoney团队出品 随着互联网技术的飞速发展,PHP作为后端开发领域的热门语言也在不断演进。近期,PHP8的发布引起了广泛关注。本文将为您详细介绍PHP8的新特性以及性能优化,并通过具体示例帮助您更好地理解和应用这些新特性。 一、PH…...
2024年06月 Scratch 图形化(四级)真题解析#中国电子学会#全国青少年软件编程等级考试
Scratch图形化等级考试(1~4级)全部真题・点这里 一、单选题(共10题,共30分) 第1题 运行下列程序,输入单词“PLAY”,最后角色说?( ) A:LY4AP B:AP4LY C:YA4PL D:PL4AY 答案:B 根据程序分析可知,首先获取单词字符数,然后奇数位的字母放在字符数左侧,偶数位…...
书生大模型全链路开源体系
书生大模型全链路开源体系 数据 预训练 微调 评测 部署 应用...
极简聊天室-websocket版(双向通信)
我们知道WebSocket是可以双向通信的,把极简聊天室代码又改了一下,前端发信息到后端也使用websocket,其实代码量更少了。。。 const express require(express); const app express(); var wsServer require(express-ws)(app)var msgs[];ap…...
从小白到架构师 | 缓存预热
缓存预热指的是在系统启动或上线前,提前将经常访问的数据加载到缓存中,以避免在系统刚启动时,用户大量请求直接访问数据库,导致数据库压力过大或系统性能下降。通过缓存预热,可以确保系统一上线就能提供快速的响应时间…...
Modbus -- TCP协议
MODBUS TCP协议是一种基于TCP/IP协议的Modbus变种,它允许Modbus协议在以太网网络上运行,使得设备之间可以通过IP网络交换数据。 一:协议概述 modbus_TCP协议:走的是网口,所以需要创建TCPclient对象进行通信,和modubus-RTU协议最大的区别是&a…...
个人网站设计提纲/推广普通话心得体会
均值为0,方差为0.01 均值为0,方差为0.09 代码如下: %imnoise demo f imread(cameraman.tif); %fnoise imnoise(f, gaussian); %增加均值为0, 方差为0.01得噪声 fnoise imnoise(f, gaussian, 128); %增加均值为2, …...
什么是品牌网站建设/南宁哪里有seo推广厂家
目录 set的介绍 map的介绍 map的总结 set的介绍 1、set是按照一定次序存储元素的容器 2、在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可…...
传媒网站建设/seo网站优化培训班
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:最多提取子串数目 题目 给定…...
wordpress彩色标签云设置方法/网站外链优化方法
Android上面为很多库做了kotlin拓展,但是需要引入为kotlin拓展的库才能使用某些方式,比如以下的方式 private val aViewModel: AViewModel by viewModels()https://developer.android.google.cn/kotlin/ktx/extensions-list...
温江做网站公司/班级优化大师下载安装最新版
文章目录问题描述解题报告实现代码参考资料问题描述 魔法王国一共有n个城市,编号为0~n-1号,n个城市之间的道路连接起来恰好构成一棵树。 小易现在在0号城市,每次行动小易会从当前所在的城市走到与其相邻的一个城市,小易最多能行动L次。 如果小易到达过某个城市就视为小易游历过…...
常德哪里有做网站/网站优化怎么做
规范化齐次坐标的作用:可将图形变换表示为图形点集规范化次坐标矩阵与某一变换矩阵相乘的形式。 平移变换比例变换旋转变换 对称变换 错位变换相对任一参考点的二维几何变换 相对任意方向的二维几何变换...