Spring aliasFor for Annotations with Target(PARAMETER)

时间:2016-08-08 11:53:18

标签: java spring spring-mvc spring-boot spring-annotations

我正在尝试使用aliasFor annotation的spring-annotation来为弹簧创建自定义注释 RequestParam

简单地'扩展/替换'

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {

   @AliasFor("name")
   String value() default "";

   ----
}

带有我的注释

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface QueryParam {

    @AliasFor(annotation = RequestParam.class, attribute = "name")
    String name() default "";

    @AliasFor(annotation = RequestParam.class, attribute = "required")
    boolean required() default false;

    @AliasFor(annotation = RequestParam.class, attribute = "defaultValue")
    String defaultValue() default ValueConstants.DEFAULT_NONE;

}

这样会抛出异常

org.springframework.core.annotation.AnnotationConfigurationException:   @AliasFor declaration on attribute [name] in annotation [package.QueryParam] declares an alias for attribute [name] in meta-annotation [org.springframework.web.bind.annotation.RequestParam] which is not meta-present.

问题是如果没有在QueryParam上注释RequestParam,那么这不起作用。并且不可能将RequestParam作为PARAMETER的目标。

@RequestParam <--This is not possible. 
public @interface QueryParam

那么有另一种方法来实现这一目标吗?

1 个答案:

答案 0 :(得分:5)

基本上你现在不可能实现的目标,至少在Spring v 4.3.3中存在两个主要问题,第一个问题是像@RequestParam这样的注释是用{{1}声明的。这使得它不可能被用作元注释的一部分。此外,Spring MVC使用@Target(ElementType.PARAMETER)查找方法参数的注释,该注释不支持元注释或组合注释。但是如果你真的需要一些自定义,你可以使用org.springframework.core.MethodParameter.getParameterAnnotations()而不是元注释。

所以你的代码看起来像

HandlerMethodArgumentResolver

然后使用@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface QueryParam { String name() default ""; boolean required() default false; String defaultValue() default ValueConstants.DEFAULT_NONE; } 添加您需要的自定义逻辑。

HandlerMethodArgumentResolver

然后我们需要注册我们的public class QueryParamResolver implements HandlerMethodArgumentResolver { public boolean supportsParameter(MethodParameter parameter) { return parameter.getParameterAnnotation(QueryParam.class) != null; } public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { QueryParam attr = parameter.getParameterAnnotation(QueryParam.class); // here you can use any logic which you need return webRequest.getParameter(attr.value()); } }

HandlerMethodArgumentResolver

最后让我们使用我们的自定义注释

@Configuration
@EnableWebMvc
public class Config extends WebMvcConfigurerAdapter {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
      argumentResolvers.add(new QueryParamResolver());
    }
}