覆盖在Interface上应用的自定义运行时注释的值

时间:2017-09-26 21:18:51

标签: java annotations wildfly

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,所以这是违反直觉但ResourceInfogetResourceMethod分到父方法,但getResourceClass指向子类。

0 个答案:

没有答案