在Spring中,`HandlerMethodArgumentResolver` 是一个非常强大的接口,用于自定义控制器方法参数的解析逻辑。以下是一个完整的示例,展示如何使用 `HandlerMethodArgumentResolver` 并结合自定义注解来实现特定的参数解析逻辑。
### **1. 定义自定义注解**
首先,定义一个自定义注解,用于标记需要特殊处理的参数。例如,定义一个 `@CurrentUser` 注解,用于注入当前用户信息:
```java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.PARAMETER) // 仅适用于方法参数
@Retention(RetentionPolicy.RUNTIME) // 运行时保留
public @interface CurrentUser {
}
```
### **2. 创建自定义 `HandlerMethodArgumentResolver`**
接下来,创建一个自定义的 `HandlerMethodArgumentResolver` 实现类,用于解析带有 `@CurrentUser` 注解的参数:
```java
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;
import javax.servlet.http.HttpServletRequest;
public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
// 检查参数是否带有 @CurrentUser 注解,并且类型是否为 User 类型
return parameter.hasParameterAnnotation(CurrentUser.class) && parameter.getParameterType().equals(User.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
// 获取当前用户信息,这里假设从请求中获取用户ID,并根据ID获取用户信息
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
String userId = request.getHeader("X-User-Id"); // 假设用户ID存储在请求头中
return getUserById(userId); // 获取用户信息
}
private User getUserById(String userId) {
// 这里是你的逻辑来获取当前用户,例如从数据库中查询
// 返回一个示例用户
return new User(userId, "John Doe");
}
}
```
### **3. 注册自定义 `HandlerMethodArgumentResolver`**
在Spring配置中注册自定义的 `HandlerMethodArgumentResolver`,使其生效:
```java
import org.springframework.beans.factory.annotation.Autowired;
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 WebConfig implements WebMvcConfigurer {
@Autowired
private CurrentUserArgumentResolver currentUserArgumentResolver;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(currentUserArgumentResolver);
}
}
```
### **4. 使用自定义注解**
在Controller方法中使用自定义注解,注入当前用户信息:
```java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@GetMapping("/user/info")
public String getUserInfo(@CurrentUser User currentUser) {
// 使用currentUser对象,它已经被解析器填充了
return "User info for: " + currentUser.getName();
}
}
```
### **5. 测试**
启动Spring Boot应用后,访问 `/user/info` 端点,并在请求头中添加 `X-User-Id`,例如:
```
GET /user/info
Headers:
X-User-Id: 12345
```
如果一切配置正确,`CurrentUserArgumentResolver` 将会被调用,并将当前用户的信息注入到 `getUserInfo` 方法的 `currentUser` 参数中,返回类似以下内容:
```
User info for: John Doe
```
### **总结**
通过定义自定义注解并结合 `HandlerMethodArgumentResolver`,可以在Spring MVC中灵活地为特定参数添加额外的解析逻辑。这种方法使得代码更加清晰且易于维护。