Spring中可以通过实现HandlerMethodArgumentResolver接口来自定义参数装配,其原理我了解就是基于拦截器。
下面我通过讲述自定义的@CurrentUser注解来解释HandlerMethodArgumentResolver接口的使用。
注解定义
/**
* 在Controller的方法参数中使用此注解,该方法在映射时会注入当前登录的User对象
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}
实现接口,添加自定义操作
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private UserService userService;
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
//如果参数类型是User并且有CurrentUser注解则支持
if (methodParameter.getParameterType().isAssignableFrom(User.class) &&
methodParameter.hasParameterAnnotation(CurrentUser.class)) {
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
//取出鉴权时存入的登录用户Id
Long currentUserId = (Long) nativeWebRequest.getAttribute(Constants.CURRENT_USER_ID, RequestAttributes.SCOPE_REQUEST);
if (currentUserId != null) {
//从数据库中查询并返回
return userService.findOne(currentUserId);
}
throw new MissingServletRequestPartException(Constants.CURRENT_USER_ID);
}
}
代码中应用
@RequestMapping(method = RequestMethod.DELETE)
@Authorization
public ResponseEntity<ResultModel> logout(@CurrentUser User user) {
tokenManager.deleteToken(user.getId());
return new ResponseEntity<>(ResultModel.ok(), HttpStatus.OK);
}
以上这个例子就是通过HandlerMethodArgumentResolver接口和自定义注解来实现自定义参数装配。