Aop切面技术之存储用户信息
一、背景
在我们日常项目中,常常会将用户的认证信息存入缓存中,方便我们在程序执行中,进行获取用户信息。本篇文章主要是介绍使用自定义注解和AOP切面技术进行实现,这也也是非常容易使用的。
二、代码详解
2.1 自定义注解
定义一个注解,用于标记需要自动注入当前用户信息的方法。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectCurrentUser {
}
2.2 创建切面
创建一个切面来拦截所有标记了@InjectCurrentUser注解的方法,并在调用它们之前获取当前用户信息,然后作为参数传递给这些方法(注意:Java的方法签名在编译时是固定的,不能直接向现有方法添加参数。因此,这里假设我们修改方法签名以接受用户信息作为参数,或者使用其他方式如ThreadLocal)。
@Aspect
@Component
public class UserAspect { @Before("@annotation(InjectCurrentUser)") public void beforeMethod(JoinPoint joinPoint) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null && authentication.getPrincipal() instanceof UserDetails) { UserDetails userDetails = (UserDetails) authentication.getPrincipal(); UserContextHolder.setCurrentUser(userDetails); // 如果需要,可以在这里添加日志或其他逻辑 System.out.println("Setting current user: " + userDetails.getUsername()); } } // 可以添加一个@After或@AfterReturning切面来清除ThreadLocal中的用户信息 // 这样做是为了避免内存泄漏,尤其是在长时间运行的线程或线程池中 @After("@annotation(InjectCurrentUser)") public void afterMethod(JoinPoint joinPoint) { UserContextHolder.clearCurrentUser(); }
}
2.3 创建ThreadLocal存储用户信息
定义一个ThreadLocal来存储当前用户的信息(比如UserDetails)
public class UserContextHolder { private static final ThreadLocal<UserDetails> currentUser = new ThreadLocal<>(); public static void setCurrentUser(UserDetails userDetails) { currentUser.set(userDetails); } public static UserDetails getCurrentUser() { return currentUser.get(); } // 清除ThreadLocal中的用户信息,避免内存泄漏 public static void clearCurrentUser() { currentUser.remove(); }
}
2.4 业务逻辑中获取用户信息
业务逻辑中,通过UserContextHolder.getCurrentUser()来获取当前用户的信息
public class SomeService { public void someBusinessMethod() { UserDetails user = UserContextHolder.getCurrentUser(); if (user != null) { // 使用用户信息进行业务逻辑处理 System.out.println("Doing something with user: " + user.getUsername()); } }
}
三、总结
内存泄漏:ThreadLocal可能会导致内存泄漏,特别是当使用线程池时,因为线程可能会被重用,而ThreadLocal中的值可能不会被自动清除。因此,在不再需要时显式清除ThreadLocal中的值是一个好习惯。
依赖注入:尽管在这个例子中我们使用了AOP来设置ThreadLocal,但在某些情况下,你可能还想通过依赖注入来传递用户信息,特别是当你需要在多个组件或服务之间共享用户信息时。然而,对于跨线程或跨方法调用的情况,ThreadLocal通常是一个更好的选择。
相关文章:
Aop切面技术之存储用户信息
一、背景 在我们日常项目中,常常会将用户的认证信息存入缓存中,方便我们在程序执行中,进行获取用户信息。本篇文章主要是介绍使用自定义注解和AOP切面技术进行实现,这也也是非常容易使用的。 二、代码详解 2.1 自定义注解 定义…...
FreeBSD 针对OpenSSH 高危漏洞发布紧急补丁
近日,FreeBSD 项目的维护者针对OpenSSH 高危漏洞发布了紧急补丁。该漏洞被追踪为 CVE-2024-7589,CVSS 得分为 7.4(最高分为 10.0)。通过利用该漏洞,黑客能够在权限提升的情况下远程执行任意代码。 根据上周发布的一份…...
【C语言小项目】五子棋游戏
目录 前言 一、游戏规则 1.功能分析 2.玩法分析 3.胜负判定条件 二、游戏实现思路 三、代码实现与函数封装 1.项目文件创建 2.头文件说明 3.函数封装 1)菜单实现 2)进度条实现 3)main函数实现 4)Game函数 5࿰…...
基于Java语言的能源管理系统-水电气热油数据采集系统
基于Java语言的能源管理系统-水电气热油数据采集系统 介绍 适用于高能耗企业、建筑、工厂、园区的水、电、气、热、油、空压机等能源数据采集、分析、报表; 基于SpringCloud的能源管理系统-能源管理平台源码-能源在线监测平台-双碳平台源码-SpringCloud全家桶-能管…...
人工智能在肿瘤亚型分类领域的研究进展|顶刊速递·24-08-13
小罗碎碎念 文献日推主题:人工智能在肿瘤亚型分类领域的研究进展 昨天晚上在研究鼻咽癌的病理学诊断指南,看到了下面这段话的时候,我问了自己一个问题——通过AI识别出肿瘤亚型的根本目的是什么?可以衔接哪些具体的下游任务&#…...
Taro+Vue 创建微信小程序
TaroVue 创建微信小程序 一、全局安装 tarojs/cli二、项目初始化三、现在去启动项目吧 一、全局安装 tarojs/cli npm install -g tarojs/cli //安装 npm info tarojs/cli //查看安装信息 如果正常显示版本说明成功了,就直接跳到第二步吧官网说:…...
智能安全守护,寺庙安全用电解决方案
在四川省蓬溪县城北,高峰山以其千年的历史沉淀和独特的文化风貌,默默诉说着道教与佛教交融的传奇。然而,2017年5月31日凌晨的一声巨响,打破了这里的宁静,一场突如其来的大火,让这座承载着无数信徒信仰与梦想…...
加热系统加入达温即停和保温功能
加热系统加入达温即停和保温功能 引言 我们前一节, 是通过控制io口, 直接控制加热的开关, 但是这太简单粗暴了, 如果只是那样, 和普通的家居电器,是没区别的, 我们想要更智能一点, 就是像咱们自己家的热水壶那样, 水烧滚了(水温达到100摄氏度), 就自动停止了. 加热功能&a…...
C++_2_ inline内联函数 宏函数(2/3)
C推出了inline关键字,其目的是为了替代C语言中的宏函数。 我们先来回顾宏函数: 宏函数 现有个需求:要求你写一个Add(x,y)的宏函数。 正确的写法有一种,错误的写法倒是五花八门,我们先来“见不贤而自省也。” // …...
ROS执行多个节点报错(遥控运动及SLAM建图)
今天在实体机器人中同时执行多个ROS节点: roslaunch rei_robot_base oryxbot_base.launchroslaunch robot_joy robot_joy.launchroslaunch oryxbot_slam oryxbot_slam_local.launch结果全部报错退出了 现在换一种执行方式: roscoreroslaunch rei_robot_base oryxbot_base.la…...
Spring Boot项目中实现文件的上传、下载和预览功能
在Spring Boot项目中实现文件的上传、下载和预览功能,可以通过使用Spring MVC的MultipartFile接口来处理文件上传,并使用HttpServletResponse或Resource来实现文件下载和预览。下面是如何实现这些功能的完整示例。 1. 引入依赖 确保在pom.xml中引入了S…...
【JAVA入门】Day21 - 时间类
【JAVA入门】Day21 - 时间类 文章目录 【JAVA入门】Day21 - 时间类一、JDK7前的时间相关类1.1 Date1.2 SimpleDateFormat1.3 Calendar 二、JDK8新增的时间相关类2.1 Date 相关类2.1.1 ZoneId 时区2.1.2 Instant 时间戳2.1.3 ZoneDateTime 带时区的时间 2.2 DateTimeFormat 相关…...
SQL server数据库备份和还原
新手小白都懂的sql server数据库备份和还原 一、备份 1.打开sql server数据库找到 2.展开找到对应的数据库文件 鼠标右击—任务–备份 3.复制名称 4.复制完点击添加 5.点击添加完之后再次点击查找路径 6.分别两个路径 原路径和新路径 (新路径是找到原路径新建了一…...
B站搜索建库架构优化实践
前言 搜索是B站的重要基础功能,需要对包括视频、评论、图文等海量的站内优质资源建立索引,处理来自用户每日数亿的检索请求。离线索引数据的正确、高效产出是搜索业务的基础。我们在这里分享搜索离线架构整体的改造实践:从周期长,…...
XSS反射实战
目录 1.XSS向量编码 2.xss靶场训练(easy) 2.1第一关 2.2第二关 方法一 方法二 2.3第三关 2.4第四关 2.5第五关 2.6第六关 2.7第七关 第一种方法: 第二种方法: 第三个方法: 2.8第八关 1.XSS向量编码 &…...
远程消息传递的艺术:NSDistantObject在Objective-C中的妙用
标题:远程消息传递的艺术:NSDistantObject在Objective-C中的妙用 引言 在Objective-C的丰富生态中,NSDistantObject扮演着至关重要的角色,特别是在处理分布式系统中的远程消息传递。它允许对象之间跨越不同地址空间进行通信&…...
指向派生类的基类指针、强转为 void* 再转为基类指针、此时调用虚函数会发生什么?
指向派生类的基类指针、强转为 void* 再转为基类指针、此时调用虚函数会发生什么? 1、无论指针类型怎么转,类对象内存没有发生任何变化,还是vfptr指向虚函数表,下面是成员变量,这在编译阶段就已经确定好了;…...
操作系统(Linux实战)-进程创建、同步与锁、通信、调度算法-学习笔记
1. 进程的基础概念 1.1 进程是什么? 定义: 进程是操作系统管理的一个程序实例。它包含程序代码及其当前活动的状态。每个进程有自己的内存地址空间,拥有独立的栈、堆、全局变量等。操作系统通过进程来分配资源(如 CPU 时间、内…...
react的setState中为什么不能用++?
背景: 在使用react的过程中产生了一些困惑,handleClick函数的功能是记录点击次数,handleClick函数被绑定到按钮中,每点击一次将通过this.state.counter将累计的点击次数显示在页面上 困惑: 为什么不能直接写prevStat…...
2.2算法的时间复杂度与空间复杂度——经典OJ
本博客的OJ标题均已插入超链接,点击可直接跳转~ 一、消失的数字 1、题目描述 数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗? 2、题目分析 (1)numsS…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
