带有目标的注释的 Spring aliasFor(PARAMETER) [英] Spring aliasFor for Annotations with Target(PARAMETER)

查看:37
本文介绍了带有目标的注释的 Spring aliasFor(PARAMETER)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过使用 aliasFor 注释来使用 spring 的元注释来为 spring 创建自定义注释 RequestParam

I am trying to use the Meta-annotation of spring using the aliasFor annotation to create a custom annotation for the springs 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 目标.

Problem is that without the RequestParam annotated on the QueryParam this doesn't work. And it is not possible to put the RequestParam as it PARAMETER targeted.

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

那么还有其他方法可以实现吗?

So is there another way to achieve this ?

推荐答案

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

Basically what you want to achieve is not possible now, at least for the Spring v 4.3.3 There are main two problems, the first one is the fact that annotations like @RequestParam are declared with @Target(ElementType.PARAMETER) which make it impossible to be used as part of meta annotations. Furthermore, Spring MVC looks up annotations on method parameters using org.springframework.core.MethodParameter.getParameterAnnotations() which does not support meta-annotations or composed annotations. But if you really need some customizations there you can use HandlerMethodArgumentResolver instead of meta annotations.

所以你的代码看起来像

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

   String name() default "";

   boolean required() default false;

   String defaultValue() default ValueConstants.DEFAULT_NONE;

}

然后使用 HandlerMethodArgumentResolver 添加您需要的自定义逻辑.

Then using the HandlerMethodArgumentResolver add the custom logic which you need.

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

Then we need to register our HandlerMethodArgumentResolver

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

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

And last lets use our custom annotation

 @GetMapping("/test")
 public String test(@QueryParam("foo") String foo){
      // something here 
 }

这篇关于带有目标的注释的 Spring aliasFor(PARAMETER)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆