Spring Boot自定义注解获取当前登录用户信息

写在前面

在项目开发过程中,难免都要获取当前登录用户的信息。通常的做法,都是开发一个获取用户信息的接口。

如果在本项目中,多处都需要获取登录用户的信息,难不成还要调用自己写的接口吗?显然不用!

以往的项目经验里,都是使用用户对应的Service获取,今天使用自定义注解对其进行数据绑定,从而获取登录用户信息。

步骤一:编写自定义注解

先自定义一个用于绑定登录用户信息的注解,且运行时有效。

代码如下:

java 复制代码
/**
 * 当前登录用户信息注解
 */
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CurrentUser{
    
}

步骤二:自定义UserResolver

Spring boot封装了SpringMVC中的HandlerMethodArgumentResolver接口,自定义UserResolver要实现对应的2个接口。

代码如下:

java 复制代码
/**
 * 当前登录用户Resolver
 */
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {

	@Autowired
	private UserService userService;

	@Override
	public boolean supportsParameter(MethodParameter methodParameter) {
		//判断方法参数是否带有@CurrentUser注解且参数类型为User或其子类
		return methodParameter.hasParameterAnnotation(CurrentUser.class) && User.class.isAssignableFrom(methodParameter.getParameterType());
	}

	@Override
	public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
		//获取当前登录用户
		return userService.getCurrent();
	}

}

步骤三:WebMvcConfig配置自定义解析器

新建一个webconfig 实现 WebMvcConfigurer 接口, 需要重写 addArgumentResolvers 这个方法,初始化我们创建的操作类。

代码如下:

java 复制代码
/**
 * 配置自定义解析器
 */
@Configuration
public class MvcConfig implements WebMvcConfigurer{

    @Bean
	public CurrentUserMethodArgumentResolver currentUserMethodArgumentResolver() {
		return new CurrentUserMethodArgumentResolver();
	}

	@Override
	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
		argumentResolvers.add(currentUserMethodArgumentResolver());
	}
}

步骤四:编写代码测试

java 复制代码
@RequestMapping(value = "/getUser", method = RequestMethod.GET)
public Map<String, Object> queryUser( @CurrentUser UserInfoVO userInfo) {
    System.out.println(userInfo);
}

小结

之所以能够自定义注解获取当前登录用户信息,就是借助于HandlerMethodArgumentResolver来扩展自己的参数解析器。

在resolveArgument接口中编写对应获取登录用户信息的逻辑代码。举个栗子,有的系统是从数据库中获取数据,有的则把对应数据放在redis中。所以在这里从不同地方获取即可。


The end.

相关推荐
lingran__3 分钟前
Linux 基础常用指令万字详解(上)|文件目录命令,结合底层原理剖析
linux·运维·服务器·后端·centos·linux基础指令
情可轻 秦任之25 分钟前
ASP.NET页面优化,性能提升8倍的方法
后端·asp.net
雾喔34 分钟前
算法练习7
java·数据结构·算法
王中阳Go1 小时前
用TRAE Work批量优化学员简历,原来2天的活现在2小时就干完了
后端·面试·agent
Zane19941 小时前
同一个 list 为什么能被两个 for 循环同时遍历?一文讲透可迭代对象与迭代器的真相
后端·python
他们叫我秃子1 小时前
前端开发转 Go 全栈(四):代码写在前面,却要最后执行?我终于搞懂了 defer
前端·后端·go
掉鱼的猫1 小时前
跳出 Fatjar 的束缚:Solon 插件的体外扩展(E-Spi)与热插拔(H-Spi)
java
Bill FANG2 小时前
从原生Java NIO到Netty重构:充电桩Socket服务端高性能改造实战
java·重构·nio
2601_955759412 小时前
Claude API 成本审计:该看哪些指标,怎么分析更靠谱
java
带刺的坐椅2 小时前
跳出 Fatjar 的束缚:Solon 插件的体外扩展(E-Spi)与热插拔(H-Spi)
java·jar·solon·plugin·fatjar