tl; dr:我正在覆盖子子类的接口的方法注释,但是注释的值没有被覆盖。
我很惊讶我在这个或任何其他网站上找不到这个问题的答案,所以我认为我的实现一定有问题,但我无法理解。
我有以下自定义注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited //This only applies to class annotations, but I tried it anyway
public @interface MyRolesAllowed {
String[] value();
}
它在这个界面上使用:
@Produces(MediaType.APPLICATION_JSON)
public interface IRESTfulCRUDResource<T> {
@GET
@Path("/")
@MyRolesAllowed("ADMIN")
public Response ws(@Context UriInfo uriInfo);
}
这实现为:
@Stateless
@Produces(MediaType.APPLICATION_JSON)
public abstract class BaseCRUDResource<T> implements IRESTfulCRUDResource<T> {
@Override
public Response wsQuery(@Context UriInfo uriInfo) {
//...
}
}
我只是在这个类中重写以更改默认注释:
@Stateless
@Path("/something")
public class SomeResource extends BaseCRUDResource<Someclass> {
@Override
@MyRolesAllowed({"ADMIN", "USER"})
public Response wsQuery(@Context UriInfo uriInfo) {
return super.wsQuery(uriInfo);
}
}
这全部托管在Wildfly服务器上,我使用以下拦截器来处理注释:
@Provider
@Priority(Priorities.AUTHORIZATION)
public class AuthorizationInterceptor implements ContainerRequestFilter {
public void filter(ContainerRequestContext requestContext) throws IOException {
Method resourceMethod = resourceInfo.getResourceMethod();
// I checked and at this point:
// resourceInfo.getResourceClass().getSimpleName() == "SomeResource"
String[] roles = resourceMethod.getAnnotation(MyRolesAllowed.class).value();
// Now, I checked and at this point:
// roles = {"ADMIN"}
// In my understanding, it should be {"ADMIN", "USER"},
// because I'm overriding the annotation on the child
// class, and resourceMethod points to the child method.
// What's wrong?
}
}
所以,正如最后一条评论中所述,我期待父母的注释被孩子的注释覆盖,但它没有发生。 This question是注释值覆盖的示例。
我也尝试使用resourceMethod.getAnnotationsByType
,但它提供了相同的值。
我误解了什么吗?
更新:@JohnBollinger在评论部分指出,我检查了resourceMethod.getDeclaringClass() == IRESTfulCRUDResource
,所以这是违反直觉但ResourceInfo的getResourceMethod
分到父方法,但getResourceClass
指向子类。