以@CurrentUser注解为例,通过在Controller的方法参数上加入@CurrentUser 注解来注入当前登录用户对象。
第一步:创建maven工程argumentResolver_demo并配置pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<groupId>cn.javahorse</groupId>
<artifactId>argumentResolver_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
第二步:创建User实体类
package cn.javahorse.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
@Data
@AllArgsConstructor
public class User implements Serializable {
private Long id;
private String username;
}
第三步:创建CurrentUser注解,注意需要加入
注解目标:@Target({ElementType.PARAMETER})、
注解保留策略:@Retention(RetentionPolicy.RUNTIME)
package cn.javahorse.anno;
import java.lang.annotation.*;
/**
* 绑定当前登录用户
*/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}
第四步:创建参数解析器类,需要实现HandlerMethodArgumentResolver接口, 注意选对parameter.hasParameterAnnotation方法,因为是给参数加注解,不是给方法(parameter.hasMethodAnnotation)加注解。
package cn.javahorse.resolver;
import cn.javahorse.anno.CurrentUser;
import cn.javahorse.entity.User;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
/**
* 自定义参数解析器
*/
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
public CurrentUserMethodArgumentResolver() {
System.out.println("CurrentUserMethodArgumentResolver自定义参数解析器初始化...");
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
//如果Controller的方法参数类型为User同时还加入了CurrentUser注解,则返回true
if (parameter.getParameterType().equals(User.class) &&
parameter.hasParameterAnnotation(CurrentUser.class)) {
return true;
}
return false;
}
//当supportsParameter方法返回true时执行此方法
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
System.out.println("参数解析器...");
//此处直接模拟了一个User对象,实际项目中可能需要从请求头中获取登录用户的令牌然后进行解析,
//最终封装成User对象返回即可,这样在Controller的方法形参就可以直接引用到User对象了
User user = new User(1L,"admin");
return user;
}
}
第五步:创建配置类,用于注册自定义参数解析器
package cn.javahorse.config;
import cn.javahorse.resolver.CurrentUserMethodArgumentResolver;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@Configuration
public class ArgumentResolverConfiguration implements WebMvcConfigurer {
public CurrentUserMethodArgumentResolver getCurrentUserMethodArgumentResolver(){
return new CurrentUserMethodArgumentResolver();
}
@Override
//注册自定义参数解析器
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(getCurrentUserMethodArgumentResolver());
}
}
第六步:创建UserController,并加入参数注解@CurrentUser
package cn.javahorse.controller;
import cn.javahorse.entity.User;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "/user")
public class UserController {
//获取当前系统登录用户
@GetMapping("/login")
public String getCurrentUser(@CurrentUser User user) {
String name = user.getUsername();
System.out.println("UserController getCurrentUser方法...");
return user.toString();
}
}
第七步:创建启动类
package cn.javahorse;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ArgumentResolverApp {
public static void main(String[] args) {
SpringApplication.run(ArgumentResolverApp.class,args);
}
}
完成自定义注解。