问题
I am trying to use the Meta-annotation of spring using the aliasFor annotation to create a custom annotation for the springs RequestParam
Simply 'extend/replace'
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
@AliasFor("name")
String value() default "";
----
}
with my annotation
@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;
}
This way it throws the Exception
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.
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 ?
回答1:
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.
So you code will look something like
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface QueryParam {
String name() default "";
boolean required() default false;
String defaultValue() default ValueConstants.DEFAULT_NONE;
}
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());
}
}
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
}
来源:https://stackoverflow.com/questions/38828543/spring-aliasfor-for-annotations-with-targetparameter