自己做动漫头像的网站,智慧团建登录平台入口,南山高端网站建设,微信公众号自己微网站吗一、背景
在我们日常项目中#xff0c;常常会将用户的认证信息存入缓存中#xff0c;方便我们在程序执行中#xff0c;进行获取用户信息。本篇文章主要是介绍使用自定义注解和AOP切面技术进行实现#xff0c;这也也是非常容易使用的。
二、代码详解
2.1 自定义注解
定义…一、背景
在我们日常项目中常常会将用户的认证信息存入缓存中方便我们在程序执行中进行获取用户信息。本篇文章主要是介绍使用自定义注解和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 ThreadLocalUserDetails 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通常是一个更好的选择。